Domanda

sovrascrivo NSURLProtocol e necessità di risposta HTTP ritorno con specifica statusCode. NSHTTPURLResponse non ha statusCode setter, così ho provato a sostituire con:

@interface MyHTTPURLResponse : NSHTTPURLResponse {} 

@implementation MyHTTPURLResponse

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

metodo ignorato startLoading di NSURLProtocol assomiglia a questo:

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

Ma questo approccio non funziona, la risposta creato nel NSURLProtocol è sempre con statusCode = 0 sulla pagina web. Allo stesso tempo le risposte che vengono restituiti dalla rete da NSURLConnection avere normali StatusCodes attesi.

Qualcuno può aiutare con idee come impostare statusCode esplicitamente creato NSURLResponse? Grazie.

È stato utile?

Soluzione

Ho implementato metodo init personalizzato utilizzando seguente codice:

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

Altri suggerimenti

Ecco una soluzione migliore.

Su iOS 5.0 e su voi non c'è bisogno di fare pazzie con le API private o NSHTTPURLResponse sovraccaricare più.

Per creare un NSHTTPUTLResponse con il codice di stato proprio e le intestazioni, è ora possibile utilizzare semplicemente:

initWithURL:statusCode:HTTPVersion:headerFields:

Il che non è documentato nella documentazione generata, ma è effettivamente presente nel file di intestazione NSURLResponse.h e anche contrassegnato come un'API pubblica che è disponibile su OS X 10.7 e iOS 5.0.

Si noti inoltre che se si sta utilizzando il trucco NSURLProtocol per effettuare chiamate da un XMLHTTPRequest UIWebView, che è necessario impostare l'intestazione Access-Control-Allow-Origin in modo appropriato. In caso contrario, i calci di sicurezza XMLHTTPRequest e anche se il NSURLProtocol riceverà e gestirà la richiesta, non sarà in grado di inviare un back di risposta.

U ottenere il codice di stato da solo l'URLResponse. Non c'è bisogno di impostare in modo esplicito: -

    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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top