2010-12-08 4 views
9

I et passer outre NSURLProtocol besoin de retourner une réponse HTTP avec statusCode spécifique. NSHTTPURLResponse n'a pas setter statusCode, donc j'ai essayé de passer outre avec:Comment configurer statusCode dans NSURLResponse

@interface MyHTTPURLResponse : NSHTTPURLResponse {} 

@implementation MyHTTPURLResponse 

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

surchargée 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 sur la page Web. En même temps, les réponses renvoyées à partir du réseau par NSURLConnection ont des statusCodes normalement attendus.

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

+0

Avez-vous trouvé une solution à ce problème? – TomSwift

Répondre

4

J'ai implémenté la méthode d'initialisation personnalisée en utilisant le 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]; 
+0

Merci pour votre réponse. J'ai résolu votre problème et j'ai obtenu statusCode 200. Cela résout mon problème, j'avais exactement besoin de l'état 200. Mais je n'ai pas réussi à définir un statut arbitraire: quel que soit statusCode en invocation par NSInvocation statusCode dans ready NSHTTPURLResponse est 200. Avez-vous essayé d'autres statusCodes ? Quoi qu'il en soit, je marque cela comme une réponse, thnx. – okonov

+0

Juste essayé - Je peux définir n'importe quel code d'état (j'ai réglé 215). Et c'est la même chose sur la page Web - 215. –

4

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); 
+0

Merci pour votre réponse. Mais je n'ai pas besoin d'obtenir statusCode de réponse http du réseau. Je crée moi-même NSURLResponse pour le renvoyer à l'intérieur de NSURLProtocol surchargé et j'ai besoin de définir statusCode de la réponse. – okonov

9

Voici une meilleure solution.

Sur iOS 5.0 et plus vous ne devez 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 est réellement présent dans le fichier d'en-tête NSURLResponse.h et aussi marqué comme une API publique disponible sur OS X 10.7 et iOS 5.0.

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

Questions connexes