Как установить StatusCode в nsurlresponse
-
10-10-2019 - |
Вопрос
Я переопределяю NSURLProtocol и должен вернуть HTTP -ответ с помощью конкретного состояния кода. Nshttpurlresponse не имеет сеттера StatusCode, поэтому я попытался переопределить его:
@interface MyHTTPURLResponse : NSHTTPURLResponse {}
@implementation MyHTTPURLResponse
- (NSInteger)statusCode {
return 200; //stub code
}
@end
Переопределенный метод начала NSURLProtocol выглядит так:
-(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];
}
}
Но этот подход не работает, ответ, созданный в NSURLProtocol, всегда содержит STATUSCODE = 0 на веб -странице. В то же время ответы, которые возвращаются из сети с помощью NSURLConnection, имеют нормальные ожидаемые статусные коды.
Может ли кто -нибудь помочь с идеями, как явно установить StatusCode для создания NSURLResponse? Спасибо
Решение
Я реализовал метод пользовательского инициирования, используя следующий код:
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];
Другие советы
Вот лучшее решение.
На iOS 5.0 и вверх вам не нужно делать ничего сумасшедшего с частными API или перегрузкой NSHTTPURLResponse
больше.
Чтобы создать NSHTTPUTLResponse
С вашим собственным кодом состояния и заголовками вы можете просто использовать:
initWithURL:statusCode:HTTPVersion:headerFields:
Который не задокументирован в сгенерированной документации, но является на самом деле присутствует в NSURLResponse.h
Файл заголовка, а также отмечен как публичный API, который доступен на OS X 10.7 и iOS 5.0.
Также обратите внимание, что если вы используете NSURLProtocol
трюк, чтобы сделать XMLHTTPRequest
звонки из UIWebView
, что вам нужно будет установить Access-Control-Allow-Origin
Заголовок соответствующим образом. В противном случае XMLHTTPRequest
Безопасность начинается, и хотя ваш NSURLProtocol
Получит и обрабатывает запрос, вы не сможете отправить ответ обратно.
Вы получите код состояния только из UrlResonse. Не нужно устанавливать это явно:-
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);