クライアントがアプリケーションで行うネットワーク呼び出しをインターセプトする必要がありますが、呼び出しは正常に完了します。ソリューションが NSURLProtocol 抽象クラスを実装し、アプリケーションに登録していることがわかりました。
これで問題が解決したように見えましたが、壁にぶつかり、タイムアウトを要求しました。iOS 5.0 をサポートする必要があるため、AFNetworking の最新バージョン 1.x を使用しています。
したがって、最初のリクエストのタイムアウトを延長する方法、または問題に対する別のより適切な解決策を見つける必要があります。
これが私がやったことです。NSURLProtocol 実装:
@implementation SLKURLProtocol
+ (NSURLRequest*) canonicalRequestForRequest:(NSURLRequest *)request
{
return request;
}
+ (BOOL) canInitWithRequest:(NSURLRequest *)request
{
return [[[request URL] scheme] isEqualToString:@"http"];
}
- (void) startLoading
{
dispatch_async(kBgQueue,
^{
NSLog(@"Intercept Request startLoading");
NSURLRequest* request = self.request;
NSLog(@"URL: %@", request.URL);
NSLog(@"HTTP Method: %@", request.HTTPMethod);
NSLog(@"Data: %@", [NSString stringWithUTF8String:[request.HTTPBody bytes]]);
});
}
- (void) stopLoading
{
dispatch_async(kBgQueue,
^{
NSLog(@"Intercept Request stopLoading");
});
}
@end
ネットワーク ViewController:
@implementation SLKViewController
- (void) viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[NSURLProtocol registerClass:[SLKURLProtocol class]];
[self initRequest];
}
- (void) initRequest
{
NSMutableURLRequest* urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://requestb.in/19kcum21"]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
[urlRequest setHTTPMethod:@"POST"];
NSMutableData* postData = [NSMutableData data];
[postData appendData:[@"REQUEST AFNETWORKING" dataUsingEncoding:NSUTF8StringEncoding]];
[urlRequest setHTTPBody:postData];
AFHTTPRequestOperation* operation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
[operation setCompletionBlockWithSuccess:
^(AFHTTPRequestOperation *operation, id responseObject)
{
NSString* serverResponse = [operation responseString];
NSLog(@"AFNetworking Response: %@", serverResponse);
} failure:
^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"AFNetworking Error: %@", error.description);
}];
[operation start];
}
@end
ログ出力は次のとおりです。
2014-01-15 17:07:19.518 InterceptionHttp[510:1303] Intercept Request startLoading 2014-01-15 17:07:19.520 InterceptionHttp[510:1303] URL: http://requestb.in/19kcum21 2014-01- 15 17:07:19.521 InterceptionHttp[510:1303] HTTP メソッド: POST 2014-01-15 17:07:19.522 InterceptionHttp[510:1303] データ: REQUEST AFNETWORKING 2014-01-15 17:07:29.522 InterceptionHttp[510: 400b] Intercept Request stopLoading 2014-01-15 17:07:29.522 InterceptionHttp[510:70b] AFNetworking エラー: エラー Domain=NSURLErrorDomain Code=-1001 「要求がタイムアウトしました。」UserInfo=0x8a5cb10 {NSErrorFailingURLStringKey= http://requestb.in/19kcum21、NSErrorFailingURLKey= http://requestb.in/19kcum21, NSLocalizedDescription=リクエストがタイムアウトしました., NSUnderlyingError=0x8a5c220 "リクエストがタイムアウトしました."}
編集:
jqyao の回答と記事を読んだ後、NSURLProtocol のサブクラス化に関するいくつかのトピックを学びました。残念ながら、HTTP をインターセプトすることはまだできません。つまり、元の要求を通常どおり続行する必要があります。
一方、URLProtocol デリゲート セレクターを呼び出す 3 行を追加すると、元の要求は続行されますが、サーバーの応答ではなく、データの応答が返されます。
startLoading
これがメソッドに追加したものです。
[[self client] URLProtocol:self didReceiveResponse:[[NSURLResponse alloc] init] cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[[self client] URLProtocol:self didLoadData:data];
[[self client] URLProtocolDidFinishLoading:self];
これが私の出力ログです。
2014-02-04 17:27:22.253 InterceptionHttp[419:3a03] Intercept Request startLoading 2014-02-04 17:27:22.254 InterceptionHttp[419:3a03] URL: http://requestb.in/tsvc14ts 2014-02- 04 17:27:22.255 InterceptionHttp[419:3a03] HTTP メソッド: POST 2014-02-04 17:27:22.255 InterceptionHttp[419:3a03] データ: { 'メッセージ': 'JSON_MESSAGE' } 2014-02-04 17: 27:22.258 InterceptionHttp[419:70b] AFNetworking 応答: {'メッセージ':'JSON_MESSAGE'} 2014-02-04 17:27:22.260 InterceptionHttp[419:1303] インターセプト リクエスト stopLoading