NSURLProtocol 可以与 NSURLSession upload, downloaddataTask 一起使用吗

Posted

技术标签:

【中文标题】NSURLProtocol 可以与 NSURLSession upload, downloaddataTask 一起使用吗【英文标题】:can NSURLProtocol work with NSURLSession upload, downloaddataTaskNSURLProtocol 可以与 NSURLSession upload, downloaddataTask 一起使用吗 【发布时间】:2015-01-12 08:09:39 【问题描述】:

我有一个自定义的 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, downloaddataTask?

【问题讨论】:

嗨!你找到解决办法了吗? 【参考方案1】:

你的想法是对的,但是你需要实现一些关键的 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];

【讨论】:

上传或下载任务需要uploadTask和downloadTask怎么办 @dopcn 你有没有想过如何让它使用uploadTask和downloadTask?

以上是关于NSURLProtocol 可以与 NSURLSession upload, downloaddataTask 一起使用吗的主要内容,如果未能解决你的问题,请参考以下文章

NSURLProtocol 详解

NSURLProtocol 使用 AJAX 超时

iOS - 将 AFNetworking 与自定义 NSURLProtocol 类一起使用

使用NSURLProtocol实现UIWebView的离线缓存

NSURLProtocol的总结

在iOS中使用NSURLProtocol进行网络代理