在 NSURLProtocol 中使用 NSURLSession
Using NSURLSession inside NSURLProtocol
我正在尝试使用 NSURLSession 为 http:// 和 https:// 连接创建一个透明的 NSURL 协议。但是目前,即使完成处理程序正在 运行,应用程序 (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:
.
解决这个问题:
- 将它们替换为
NSURLSession
委托方法。
- 创建并保留一个自定义会话,其委托是您的协议 class 实例;共享会话没有委托,因此它不会调用您的 class 的委托方法。
- 删除回调块,以便正确调用请求完成的委托方法。
我正在尝试使用 NSURLSession 为 http:// 和 https:// 连接创建一个透明的 NSURL 协议。但是目前,即使完成处理程序正在 运行,应用程序 (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:
.
解决这个问题:
- 将它们替换为
NSURLSession
委托方法。 - 创建并保留一个自定义会话,其委托是您的协议 class 实例;共享会话没有委托,因此它不会调用您的 class 的委托方法。
- 删除回调块,以便正确调用请求完成的委托方法。