NSURLResponseでstatusCodeを設定する方法
-
10-10-2019 - |
質問
NSURLProtocol をオーバーライドし、特定の statusCode を含む HTTP 応答を返す必要があります。NSHTTPURLResponse には statusCode セッターがないので、次のようにオーバーライドしようとしました。
@interface MyHTTPURLResponse : NSHTTPURLResponse {}
@implementation MyHTTPURLResponse
- (NSInteger)statusCode {
return 200; //stub code
}
@end
NSURLProtocol のオーバーライドされた startLoading メソッドは次のようになります。
-(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 で作成された応答は、Web ページでは常に statusCode = 0 になります。同時に、NSURLConnection によってネットワークから返される応答には、通常の予期される statusCode が含まれます。
作成された NSURLResponse に statusCode を明示的に設定する方法を教えてください。ありがとう。
解決
次のコードを使用してカスタムinitメソッドを実装しました。
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
ヘッダー ファイルに保存され、OS X 10.7 および iOS 5.0 で利用できるパブリック API としてもマークされています。
を使用している場合にも注意してください。 NSURLProtocol
作るためのトリック XMLHTTPRequest
からの電話 UIWebView
, を設定する必要があることを確認します。 Access-Control-Allow-Origin
ヘッダーを適当に。それ以外の場合は、 XMLHTTPRequest
セキュリティが作動し、たとえ NSURLProtocol
がリクエストを受信して処理するため、応答を返すことはできません。
u urlResponseからのみステータスコードを取得します。明示的に設定する必要はありません: -
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);