用NSURLPROTOCOL实现代理和缓存

来源:互联网 发布:python中的模型meta 编辑:程序博客网 时间:2024/05/21 19:35

原理

NSURLProtocol可以用来劫持全局的由NSURLConnection发起的网络请求,通过覆写方法,你可以获知NSURLConnection需要发起的NSURLRequest,你可以自行发起网络请求,并且把数据丢过请求的发起者。通过这种方法,一般来说,你可以实现代理和缓存等功能。 由于UIWebView也是走的这套协议,所以你甚至可以自己开发一个走代理的浏览器。

方法

注册自定义协议

[NSURLProtocol registerClass:[HSUProxyURLProtocol class]];

  

实现自定义协议

Header文件

#import <Foundation/Foundation.h>
@interface HSUProxyURLProtocol : NSURLProtocol
@end

  

Implementation文件

#import "HSUProxyURLProtocol.h" @implementation HSUProxyURLProtocol 
{
 #可以在此定义数据容器,连接等 
- (void)startLoading 
#可以这样子拿到原来的请求,用以拼装自己的请求 
NSMutableURLRequest *proxyRequest = [self.request mutableCopy]; 
- (void)stopLoading 
#请求在这里该结束了,在此终止自己的请求吧 
[connection cancel];
 }
 #这几个不是Protocol的方法,是自发起的URLConnection的回调
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
 #此方法会收到一部分或者全部的数据,可以这样子丢给原始请求的发起者 
[self.client URLProtocol:self didLoadData:sourceData]; 
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
#和上一个方法类似,这里作为错误通知 
[self.client URLProtocol:self didFailWithError:error]; 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
#这里是收到响应的头部信息,比如HTTP Header,可视情况做对self.client做相应操作,也可以不做处理 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
#自己的请求加载完成了,这样子可以通知
self.client [self.client URLProtocolDidFinishLoading:self];
 } 
+ (BOOL)canInitWithRequest:(NSURLRequest *)request 
#根据request来决定要不要劫持 
#需要特别注意的是,如果你用NSURLConnection来发起代理请求,那么那个代理请求的request也同样会经过这里来做判决,所以一定要判断是不是代理请求,然后返回NO }
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request 
#这里是干嘛的,我还没研究清楚,就简单的返回了原始值,有兴趣的话你可以研究一下 
return request; 
@end

以上我已经基本描述了每个方法是做什么的,怎么用的。 最后可以参考一下我在开源项目中的实现 Tweet4China2 另参见一个别人写的缓存 RNCachingURLProtocol

0 0
原创粉丝点击