本文转载至 http://blog.csdn.net/u014011807/article/details/39894247

NSURLProtocol 是iOS中非常重要的一个部分,我们经常会在以下地方用到它:

(1)网络请求代理转发(FQ 网络加速等)

(2)离线缓存策略

总之,只要是需要对本地的URL请求进行截获的,我们都需要使用这个东东。

IOS中我们经常使用的网络请求NSURLConnection以及WebView的页面加载都会被NSURLProtocol截获,因此这个部分的核心就是如何来用这个部分:

下面我将根据使用的步骤来描述NSURLProtocol的使用过程:

最终运行结果:

(1)首先我们需要创建一个类,继承NSURLProtocol

并且实现代理继承:

@interfaceMyURLProtocol () <NSURLConnectionDelegate>

@end

(2)注册这个协议

一般情况下,这个协议在AppDelegate文件中注册:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

[NSURLProtocol  registerClass:[MyURLProtocolclass]];

// Override point for customization after application launch.

returnYES;

}

下面就可以使用这个东东了

(3)下面准备好一段WebView的页面加载代码,这个太简单了,不详细说了,给一个参考代码:

- (void) sendRequest {

NSString *text =self.textField.text;

if (![textisEqualToString:@""]) {

NSURL *url = [NSURLURLWithString:text];

NSURLRequest *request = [NSURLRequestrequestWithURL:url];

[self.webView loadRequest:request];

}

}

(4)可以正常的使用这个NSURLProtocol只需要简单的使用下面9个方法,这九个方法是这个协议可以实现的最基本和最重要的几个方法,当然它还有很多高级的功能,这里就不一一介绍了。

最重要的9个方法如下:

<1>

@method:创建NSURLProtocol实例,NSURLProtocol注册之后,所有的NSURLConnection都会通过这个方法检查是否持有该Http请求。

@parma :

@return: YES:持有该Http请求NO:不持有该Http请求

+ (BOOL)canInitWithRequest:(NSURLRequest *)request

#pragma mark --NSURLProtocol Hold RelevantMethod 4个方法

<2-5>

@method: NSURLProtocol抽象类必须要实现。通常情况下这里有一个最低的标准:即输入输出请求满足最基本的协议规范一致。因此这里简单的做法可以直接返回。一般情况下我们是不会去更改这个请求的。如果你想更改,比如给这个request添加一个title,组合成一个新的http请求。

@parma :本地HttpRequest请求:request

@return:直接转发

+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest *)request

@method: NSURLProtocol缓存系统设置:如果有两个URL请求,并且他们是相等的,那么这里可以使用相同的缓存空间

@parma :本地HttpRequest请求:request

@return:

+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest*)b

@method:获取网站上的数据建立connect连接

@parma :

@return:

- (void)startLoading

@method:当前Connection连接取消的时候被调用。尤其要注意这个StopLoading方法,在本地NSURLRequest初始化的时候,有一个超时时间,在低速网络下,有可能页面还没来得及加载完,这个StopLoading方法就被调用了。

@parma :

@return:

- (void)stopLoading

<6-9>接收数据

#pragma mark --NSURLProtocol Delegate 4个方法

-                 (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response

-                 (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data

-                 (void)connectionDidFinishLoading:(NSURLConnection*)connection

-                 (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error

注意这里的方法中:

canInitWithRequest 会创建一个实例,YES时候,然后继续调用startLoading。这里会继续调用canInitWithRequest。陷入死循环,因此这里我们常用的做法是设置一个[NSURLProtocolsetProperty:@YESforKey:@"MyURLProtocolHandledKey"inRequest:newRequest];

这样就可以避免程序陷入死循环。

(5)下面给出一段参考代码:

@implementation MyURLProtocol

/**

@method: 创建NSURLProtocol实例,NSURLProtocol注册之后,所有的NSURLConnection都会通过这个方法检查是否持有该Http请求。

@parma :

@return: YES:持有该Http请求 NO:不持有该Http请求

*/

+ (BOOL)canInitWithRequest:(NSURLRequest *)request {

staticNSUInteger requestCount =0;

NSLog(@"Request #%u: URL = %@", requestCount++, request);

if([NSURLProtocolpropertyForKey:@"MyURLProtocolHandledKey"inRequest:request]) {

returnNO;

}

returnYES;

}

#pragma mark --NSURLProtocol Hold Relevant Method

/**

@method: NSURLProtocol抽象类必须要实现。通常情况下这里有一个最低的标准:即输入输出请求满足最基本的协议规范一致。因此这里简单的做法可以直接返回。一般情况下我们是不会去更改这个请求的。如果你想更改,比如给这个request添加一个title,组合成一个新的http请求。

@parma : 本地HttpRequest请求:request

@return: 直接转发

*/

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest*)request {

return request;

}

/**

@method: NSURLProtocol缓存系统设置:如果有两个URL请求,并且他们是相等的,那么这里可以使用相同的缓存空间

@parma : 本地HttpRequest请求:request

@return:

*/

+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b {

return [superrequestIsCacheEquivalent:atoRequest:b];

}

- (void)startLoading {

NSMutableURLRequest *newRequest = [self.requestmutableCopy];

[NSURLProtocolsetProperty:@YESforKey:@"MyURLProtocolHandledKey"inRequest:newRequest];

self.connection = [NSURLConnectionconnectionWithRequest:newRequestdelegate:self];

}

/**

@method: 当前Connection连接取消的时候被调用

@parma :

@return:

*/

- (void)stopLoading {

[self.connectioncancel];

self.connection =nil;

}

#pragma mark --NSURLProtocol Delegate

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

[self.clientURLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

[self.clientURLProtocol:selfdidLoadData:data];

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

[self.clientURLProtocolDidFinishLoading:self];

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {

[self.clientURLProtocol:selfdidFailWithError:error];

}

@end

转载于:https://www.cnblogs.com/Camier-myNiuer/p/5527910.html

IOS网络篇1之截取本地URL请求(NSURLProtocol)相关推荐

  1. 封装网络请求 - iOS网络篇

    一.简单说明 1.分析项目对网路请求(AFN框架)的依赖 项目中,多个控制器都使用了AFN框架发送网络请求,如果AFN2.0存在重大BUg,或者是升级至3.0版本,那么对于整个项目都是及其危险的,所有 ...

  2. iOS网络编程之同步、异步、请求队列

    1. 同步意为着线程阻塞,在主线程中使用此方法会不响应任何用户事件.所以,在应用程序设计时,大多被用在专门的子线程增加用户体验,或用异步请求代替. - (IBAction)grabURL:(id)se ...

  3. iOS开发网络篇—搭建本地服务器

    iOS开发网络篇-搭建本地服务器 一.简单说明 说明:提前下载好相关软件,且安装目录最好安装在全英文路径下.如果路径有中文名,那么可能会出现一些莫名其妙的问题. 提示:提前准备好的软件 apache- ...

  4. iOS网络缓存扫盲篇--使用两行代码就能完成80%的缓存需求

    原文地址:https://github.com/ChenYilong/ParseSourceCodeStudy/blob/master/02_Parse的网络缓存与离线存储/iOS网络缓存扫盲篇.md ...

  5. 02.iOS开发网络篇—HTTP协议

    iOS开发网络篇-HTTP协议 说明:apache tomcat服务器必须占用8080端口 一.URL 1.基本介绍 URL的全称是Uniform Resource Locator(统一资源定位符) ...

  6. ⑧(网络篇)、《史上最全iOS八股文面试题》2022年,金三银四我为你准备了,iOS《1000条》笔试题以及面试题(包含答案)。带面试你过关斩将,(赶紧过来背iOS八股文)

    iOS面试题 一共分为笔试题和面试题两部分 笔试题 一共分为10个 总共613题 面试题 一共400题 笔试题 一个10个系列 分别为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ...

  7. iOS开发网络篇—多线程断点下载

    iOS开发网络篇-多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...

  8. iOS开发网络篇—使用ASI框架进行文件下载

    iOS开发网络篇-使用ASI框架进行文件下载 说明:本文介绍iOS网络编程中经常用到的框架ASI,如何使用该框架进行文件的下载. 一.简单介绍 代码示例: 1 #import "YYView ...

  9. iOS开发网络篇—数据缓存

    iOS开发网络篇-数据缓存 一.关于同一个URL的多次请求 有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的. 上面的情况会造成以 ...

最新文章

  1. win7下安装memcached出现failed to install service or service already installed解决办法
  2. PADS 9.5安装教程附安装包资源
  3. 牛客小白月赛12:月月给华华出题(欧拉函数)
  4. Ubuntu-16.04安装Xdebug-2.2.5及相关介绍
  5. mysql 在线备份脚本,MySQL备份脚本
  6. 树莓派配置文档config.txt说明
  7. spss软件测试题题库,spss题库_Spss软件可以算试题的区分度吗怎么算_淘题吧
  8. logistic回归分析优点_漫谈数据分析之建模算法
  9. java软件工程师工作业绩_java软件工程师的工作描述怎么写
  10. 数据库容灾技术之–数据容灾技术比较
  11. 160603、使用pd4ml.jar和ss_css2.jar转pdf的工具类
  12. 2011浙江省公务员考试申论大作文的写作
  13. 为什么总是封板又打开涨停_一旦持有个股出现涨停板,却封不住反复打开,意味着什么?...
  14. 基于JCA安全体系的封装
  15. 用lingo解决钢管下料问题
  16. 键盘 部分 按键 ~ 需要长按才能打出来
  17. 周末之个人杂想(十五)
  18. html excel 在线查看,web在线查看服务器的Excel文件
  19. TCP/IP 报文协议学习
  20. 瑞芯微RV1126部署yolov5-face_模型转换_输出后处理C++实现

热门文章

  1. hyfsoft java_Java自动化测试框架-04 - 来给你的测试报告化个妆整个形 - (上)(详细教程)...
  2. tp3.2.3权限控制二之后台管理部分,及菜单栏目显示问题
  3. 原创Kafka学习笔记,java如何用数组生成随机数
  4. 【C++ STL】Map库使用方法
  5. Error: Cannot find module ‘webpack-cli/bin/config-yargs‘
  6. 东莞网络推广浅析网站优化中常见的引流方式有哪些?
  7. 企业网络推广方案教大家在更换服务器时降低排名影响的技巧!
  8. 网络营销——网络营销专员浅析网站推广营销关键词是重点
  9. 浅析企业网站页面设计如何才能更吸引用户注意!
  10. 积累有价值的seo资源提高网站优化效果