Come impostare statusCode in NSURLResponse
-
10-10-2019 - |
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.
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);