NSURLProtocol 可以与 NSURLSession {upload, download}dataTask 一起使用吗
can NSURLProtocol work with NSURLSession {upload, download}dataTask
我有一个自定义的 NSURLProtocol
#import <Foundation/Foundation.h>
@interface XXXURLProtocol : NSURLProtocol <NSURLSessionDataDelegate, NSURLSessionTaskDelegate>
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSURLSessionTask *task;
@end
#import "XXXURLProtocol.h"
@implementation DXYURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
if ([NSURLProtocol propertyForKey:YXURLProtocolHandled inRequest:request]) {
return NO;
}
NSString *scheme = [[request URL] scheme];
NSDictionary *dict = [request allHTTPHeaderFields];
return [dict objectForKey:@"custom_header"] == nil &&
([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame);
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
return request;
}
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a
toRequest:(NSURLRequest *)b {
return [super requestIsCacheEquivalent:a toRequest:b];
}
- (void)startLoading
{
NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
//add custom headers
[XXXURLProtocol addCustomHeaders:mutableReqeust];
[NSURLProtocol setProperty:@(YES)
forKey:YXURLProtocolHandled
inRequest:mutableReqeust];
NSURLSessionConfiguration *config;
config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.protocolClasses = @[ self ];
self.session = [NSURLSession sessionWithConfiguration:config];
self.task = [self.session dataTaskWithRequest:mutableReqeust];
[self.task resume];
}
- (void)stopLoading
{
[self.task cancel];
self.task = nil;
}
//and all other NSURLProtocolClient protocol method
@end
如何使这个自定义 NSURLProtocol 支持{上传,下载}dataTask?
你的想法是对的,但你需要实现一些关键的 URLSessionDelegate 方法来将响应和数据传递给 NSURLProtocol 客户端:
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
if( error ) {
[self.client URLProtocol:self didFailWithError:error];
} else {
[self.client URLProtocolDidFinishLoading:self];
}
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
completionHandler(NSURLSessionResponseAllow);
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
[self.client URLProtocol:self didLoadData:data];
}
我有一个自定义的 NSURLProtocol
#import <Foundation/Foundation.h>
@interface XXXURLProtocol : NSURLProtocol <NSURLSessionDataDelegate, NSURLSessionTaskDelegate>
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSURLSessionTask *task;
@end
#import "XXXURLProtocol.h"
@implementation DXYURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
if ([NSURLProtocol propertyForKey:YXURLProtocolHandled inRequest:request]) {
return NO;
}
NSString *scheme = [[request URL] scheme];
NSDictionary *dict = [request allHTTPHeaderFields];
return [dict objectForKey:@"custom_header"] == nil &&
([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame);
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
return request;
}
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a
toRequest:(NSURLRequest *)b {
return [super requestIsCacheEquivalent:a toRequest:b];
}
- (void)startLoading
{
NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
//add custom headers
[XXXURLProtocol addCustomHeaders:mutableReqeust];
[NSURLProtocol setProperty:@(YES)
forKey:YXURLProtocolHandled
inRequest:mutableReqeust];
NSURLSessionConfiguration *config;
config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.protocolClasses = @[ self ];
self.session = [NSURLSession sessionWithConfiguration:config];
self.task = [self.session dataTaskWithRequest:mutableReqeust];
[self.task resume];
}
- (void)stopLoading
{
[self.task cancel];
self.task = nil;
}
//and all other NSURLProtocolClient protocol method
@end
如何使这个自定义 NSURLProtocol 支持{上传,下载}dataTask?
你的想法是对的,但你需要实现一些关键的 URLSessionDelegate 方法来将响应和数据传递给 NSURLProtocol 客户端:
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
if( error ) {
[self.client URLProtocol:self didFailWithError:error];
} else {
[self.client URLProtocolDidFinishLoading:self];
}
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
completionHandler(NSURLSessionResponseAllow);
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
[self.client URLProtocol:self didLoadData:data];
}