2010-12-08 5 views
9

Ich überschreiben NSURLProtocol und müssen HTTP-Antwort mit bestimmten StatusCode zurückgeben. NSHTTPURLResponse hat nicht status Setter, also versuchte ich es außer Kraft zu setzen mit:So setzen Sie statusCode in NSURLResponse

@interface MyHTTPURLResponse : NSHTTPURLResponse {} 

@implementation MyHTTPURLResponse 

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

überschreiben startLoading Methode von NSURLProtocol sieht wie folgt aus:

-(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]; 
    } 
} 

Aber dieser Ansatz funktioniert nicht, die Antwort in NSURLProtocol erstellt ist immer mit statusCode = 0 auf der Webseite. Zur gleichen Zeit haben Antworten, die von NSURLConnection aus dem Netzwerk zurückgegeben werden, normale erwartete StatusCodes.

Kann mir bitte jemand helfen mit Ideen, wie statusCode explizit für erstellte NSURLResponse setzen? Danke.

+0

Haben Sie eine Lösung für dieses Problem gefunden? – TomSwift

Antwort

4

ich benutzerdefinierte init-Methode folgenden Code implementiert haben:

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

Vielen Dank für die Antwort. Ich habe Ihre Lösung versucht und statusCode 200. Dies löst mein Problem, ich brauchte genau Status 200. Aber ich konnte keinen willkürlichen Status setzen: was auch immer statusCode im Aufruf von NSInvocation statusCode in bereit NSHTTPURLResponse ist 200. Haben Sie andere statusCodes versucht ? Jedenfalls markiere ich das als Antwort, thnx. – okonov

+0

Ausprobiert - ich kann jeden Statuscode setzen (ich habe 215 eingestellt). Und es ist das gleiche auf der Webseite - 215. –

4

U erhalten Sie den Statuscode nur von der URLResponse. Keine Notwendigkeit, setzen sie ausdrücklich: -

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

Vielen Dank für die Antwort. Aber ich brauche nicht Status of HTTP-Antwort aus dem Netzwerk zu bekommen. Ich erstelle NSURLResponse selbst, um es innerhalb des überschriebenen NSURLProtocols zurückzugeben, und muss statusCode der Antwort setzen. – okonov

9

Hier ist eine bessere Lösung.

Auf iOS 5.0 und höher müssen Sie nichts mehr mit privaten APIs machen oder NSHTTPURLResponse überladen.

Um ein NSHTTPUTLResponse mit Ihrem eigenen Statuscode und Header zu erstellen, können Sie jetzt einfach nutzen:

initWithURL:statusCode:HTTPVersion:headerFields: 

die nicht in der erzeugten Dokumentation dokumentiert ist aber ist vorhanden tatsächlich in der NSURLResponse.h Header-Datei und auch Als öffentliche API markiert, die unter OS X 10.7 und iOS 5.0 verfügbar ist.

Beachten Sie auch, dass, wenn Sie die NSURLProtocol Trick verwenden XMLHTTPRequest Anrufe von einem UIWebView zu machen, dass Sie die Access-Control-Allow-Origin Header entsprechend eingestellt werden müssen. Andernfalls tritt die XMLHTTPRequest Sicherheit ein und obwohl Ihre NSURLProtocol die Anfrage empfängt und bearbeitet, können Sie keine Antwort zurücksenden.

Verwandte Themen