2010-12-08 3 views
9

Я переопределяю NSURLProtocol и вам нужно вернуть HTTP-ответ с определенным кодом состояния. NSHTTPURLResponse не StatusCode сеттера, поэтому я попытался изменить его с помощью:Как установить statusCode в NSURLResponse

@interface MyHTTPURLResponse : NSHTTPURLResponse {} 

@implementation MyHTTPURLResponse 

    - (NSInteger)statusCode { 
     return 200; //stub code 
    } 
@end 

Переопределенного startLoading метода NSURLProtocol выглядит следующим образом:

-(void)startLoading 
{ 
    NSString *url = [[[self request] URL] absoluteString]; 
    if([url isEqualToString:SPECIFIC_URL]){ 
     MyURLResponse *response = [[MyURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://fakeUrl"] 
     MIMEType:@"text/plain" 
     expectedContentLength:0 textEncodingName:nil]; 

     [[self client] URLProtocol:self  
      didReceiveResponse:response 
      cacheStoragePolicy:NSURLCacheStorageNotAllowed]; 

     [[self client] URLProtocol:self didLoadData:[@"Fake response string" 
      dataUsingEncoding:NSASCIIStringEncoding]]; 

     [[self client] URLProtocolDidFinishLoading:self];     

     [response release]; 

    } 
    else{ 
     [NSURLConnection connectionWithRequest:[self request] delegate:self]; 
    } 
} 

Но этот подход не работает, ответ созданный в NSURLProtocol всегда имеет статусCode = 0 на веб-странице. В то же время ответы, которые возвращаются из сети NSURLConnection, имеют нормальные ожидаемые коды состояния.

Может кто-нибудь может помочь с идеями, как установить statusCode явно для созданного NSURLResponse? Thanx.

+0

Вы нашли решение этой проблемы? – TomSwift 2011-01-31 23:21:10

ответ

4

Я реализовал метод пользовательской инициализации с помощью следующего кода:

NSInteger statusCode = 200; 
    id headerFields = nil; 
    double requestTime = 1; 

    SEL selector = NSSelectorFromString(@"initWithURL:statusCode:headerFields:requestTime:"); 
    NSMethodSignature *signature = [self methodSignatureForSelector:selector]; 

    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:signature]; 
    [inv setTarget:self]; 
    [inv setSelector:selector]; 
    [inv setArgument:&URL atIndex:2]; 
    [inv setArgument:&statusCode atIndex:3]; 
    [inv setArgument:&headerFields atIndex:4]; 
    [inv setArgument:&requestTime atIndex:5]; 

    [inv invoke]; 
+0

Благодарим за сообщение. Я пробовал ваше решение и получил statusCode 200. Это решает мою проблему, мне нужен ровно статус 200. Но мне не удалось установить произвольный статус: независимо от того, какой статусCode установлен в вызове по NSInvocation statusCode в готовом NSHTTPURLResponse 200. Вы пробовали другие statusCodes ? В любом случае я отмечаю это как ответ, thnx. – okonov 2011-08-09 20:24:28

4

U получить код состояния только из URLResponse. Нет необходимости, чтобы установить его в явном виде: -

NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&requestError]; 

    NSString *responseString = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] autorelease]; 
    NSLog(@"ResponseString:%@",responseString); 

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 
    int statusCode = [httpResponse statusCode]; 
    NSLog(@"%d",statusCode); 
+0

Благодарим за сообщение. Но мне не нужно получать statusCode ответа HTTP из сети. Я сам создаю NSURLResponse, чтобы вернуть его в переопределенном NSURLProtocol, и вам нужно установить statusCode ответа. – okonov 2010-12-08 20:25:40

9

Вот лучшее решение.

На iOS 5.0 и вам не нужно ничего делать с помощью частных API или перегружать NSHTTPURLResponse.

Чтобы создать NSHTTPUTLResponse с вашим собственным кодом состояния и заголовков, теперь вы можете просто использовать:

initWithURL:statusCode:HTTPVersion:headerFields: 

Что не документированы в сгенерированной документации, но является на самом деле присутствует в файле NSURLResponse.h заголовка, а также помеченный как общедоступный API, доступный в OS X 10.7 и iOS 5.0.

Также обратите внимание, что если вы используете NSURLProtocol трюк, чтобы сделать XMLHTTPRequest звонков с UIWebView, что вам нужно будет установить заголовок Access-Control-Allow-Origin соответствующим образом. В противном случае вы получите XMLHTTPRequest, и хотя ваш NSURLProtocol получит и обработает запрос, вы не сможете отправить ответ.

Смежные вопросы