Question

J'Override NSURLProtocol et besoin de retour réponse HTTP avec statusCode spécifique. NSHTTPURLResponse n'a pas setter statusCode, alors j'ai essayé de passer outre avec:

@interface MyHTTPURLResponse : NSHTTPURLResponse {} 

@implementation MyHTTPURLResponse

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

méthode redéfinie startLoading de NSURLProtocol ressemble à ceci:

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

Mais cette approche ne fonctionne pas, la réponse créée en NSURLProtocol est toujours avec statusCode = 0 à la page Web. Dans le même temps des réponses qui sont retournées à partir du réseau par NSURLConnection ont statusCodes normales attendues.

Quelqu'un peut-il vous plaît aider avec des idées comment configurer statusCode explicitement pour NSURLResponse créé? Thanx.

Était-ce utile?

La solution

Je l'ai mis en œuvre la méthode personnalisée init à l'aide code suivant:

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

Autres conseils

Voici une meilleure solution.

Sur iOS 5.0 et plus vous n'avez pas à faire quelque chose de fou avec des API privées ou une surcharge NSHTTPURLResponse plus.

Pour créer un NSHTTPUTLResponse avec votre propre code d'état et les en-têtes, vous pouvez maintenant utiliser simplement:

initWithURL:statusCode:HTTPVersion:headerFields:

non documenté dans la documentation générée, mais réellement présentes dans le fichier d'en-tête de NSURLResponse.h, et marqué comme une API publique qui est disponible sur OS X 10.7 et iOS 5.0.

Notez également que si vous utilisez l'astuce NSURLProtocol pour faire des appels XMLHTTPRequest d'un UIWebView, que vous devez régler correctement l'en-tête de Access-Control-Allow-Origin. Sinon, les coups de pied de sécurité XMLHTTPRequest et même si votre NSURLProtocol va recevoir et traiter la demande, vous ne serez pas en mesure d'envoyer un retour de réponse.

U obtenir le code d'état de la URLResponse seulement. Pas besoin de définir explicitement: -

    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);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top