在NSURLProtocol中使用NSURLSession

我正在尝试使用NSURLSession为http://和https://连接创build一个透明的NSURLProtocol。 然而,目前,即使正在运行完成处理程序,带有应用程序(UIWebView)的URL请求也回来了。 有人有什么想法吗? 代码如下:

#import "MyURLProtocol.h" // AppDelegate #import "AppDelegate.h" static NSString * const MyURLProtocolHandledKey = @"MyURLProtocolHandledKey"; @interface MyURLProtocol () <NSURLConnectionDelegate,NSURLSessionDelegate> @property (nonatomic, strong) NSURLConnection *connection; @property (nonatomic, strong) NSMutableData *mutableData; @property (nonatomic, strong) NSURLResponse *response; @end @implementation MyURLProtocol +(BOOL)canInitWithRequest:(NSURLRequest*)request { if ([NSURLProtocol propertyForKey:MyURLProtocolHandledKey inRequest:request]) return NO; NSString *scheme = request.URL.scheme.lowercaseString; return [scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]; } + (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request { return request; } -(void)startLoading { NSMutableURLRequest *newRequest = [self.request mutableCopy]; [NSURLProtocol setProperty:@YES forKey:@"MyURLProtocolHandledKey" inRequest:newRequest]; NSURLRequest *request = newRequest; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) { if (error != nil) { NSLog(@"There was an error"); } NSLog(@"Completiio handler ran"); self.mutableData = [NSMutableData dataWithData:data]; self.response = response; }]; [task resume]; } - (void) stopLoading { [self.connection cancel]; self.mutableData = nil; } // Delegate stuff - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.client URLProtocol:self didLoadData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [self.client URLProtocolDidFinishLoading:self]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [self.client URLProtocol:self didFailWithError:error]; } @end 

你的代码使用NSURLConnection委托传回数据给调用者,例如connectionDidFinishLoading: NSURLConnection

要解决这个问题:

  • NSURLSession委托方法replace这些。
  • 创build并保留一个自定义会话,其委托是您的协议类实例; 共享会话没有委托,所以它不会调用你的类的委托方法。
  • 删除callback块,以便正确调用请求完成的委托方法。