NSURLProtocol可以使用NSURLSession {upload,download} dataTask

时间:2015-01-12 08:09:39

标签: ios nsurlsession nsurlsessiondownloadtask nsurlsessionuploadtask nsurlsessionconfiguration

我有自定义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支持{upload,download} dataTask?

1 个答案:

答案 0 :(得分:3)

您有正确的想法,但您需要实现一些关键的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];
}