Comment mettre statusCode en NSURLResponse
-
10-10-2019 - |
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.
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);