iOSUIWebViewURL拦截

iOSUIWebViewURL拦截译者在做app开发时,因为页面的javascript文件比较大导致加载速度很慢,所以想把javascript文件打包在app里,当UIWebView需要加载该脚本时就从app本地读取,但UIWebView并不支持加载本地资源。最后从下文中找到了解决方法,第一次翻译,难免有误,大家多多指教。iCabMobile(一款iOS平台的网页浏览器)要实现一个拦截管理器来过滤页面上的广告及其他东西。它有一个简单的基于URL过滤规则的列表(通常由用户维护),当页面包含的资源(图片、js以及css等),文件的URL存在于规则列表中时,资源就不会被加载。但看一下UIWebView类的API,会发现我们没有办法知道UIWebView正在加载什么资源,更糟的是,当你希望过滤掉某些资源文件的时候,没有方法可以强制UIWebView不去加载这些文件,拦截器看起来貌似没有可能实现。当然还是有解决方案的,否则这篇文件就没什么卵用。正如上面所说,实现拦截器不能靠UIWebView,因为UIWebView没有提供任何有用的API。对UIWebView的所有请求,要找到一个能中断所有请求的切入点,我们需要先了解一下Cocoa的URLLoadingSystem,因为UIWebView是使用URLLoadingSystem从web端取数据的。我们需要的切入点NSURLCache类就是URLLoadingSystem的一部分。虽然目前iOS系统不会在磁盘上缓存任何数据(后面的iOS系统版本或许会有不同),因此在UIWebView开始加载前,NSURLCache管理的缓存数据通常为空,但UIWebView仍然会检测所请求资源文件是否存在于缓存。所以我们需要做的只是继承NSURLCache并重载其方法:1.-(NSCachedURLResponse*)cachedResponseForRequest:(NSURLRequest*)requestUIWebView请求所有资源时都会调用这个方法。因为我们只需要在这个方法里判断请求的URL是否是我们想拦截的。如果是则创建一个没有内容的假response,否则只需调用super方法即可。如下是实现细节:1.继承NSURLCache:FilteredWebCache.h:1.@interfaceFilteredWebCache:NSURLCache2.{3.}4.@end子类的主要代码FilteredWebCache.m:1.#import"FilteredWebCache.h"2.#import"FilterManager.h"3.@implementationFilteredWebCache4.-(NSCachedURLResponse*)cachedResponseForRequest:(NSURLRequest*)request5.{6.NSURL*url=[requestURL];7.BOOLblockURL=[[FilterMgrsharedFilterMgr]shouldBlockURL:url];8.if(blockURL){9.NSURLResponse*response=10.[[NSURLResponsealloc]initWithURL:url11.MIMEType:@"text/plain"12.expectedContentLength:113.textEncodingName:nil];14.NSCachedURLResponse*cachedResponse=15.[[NSCachedURLResponsealloc]initWithResponse:response16.data:[NSDatadataWithBytes:""length:1]];17.[superstoreCachedResponse:cachedResponseforRequest:request];18.[cachedResponserelease];19.[responserelease];20.}21.return[supercachedResponseForRequest:request];22.}23.@end首先判断URL是否需拦截(判断通过FilterManager类实现,类实现在此不列出)。如果需要,创建一个无内容的响应对象并把它存在cache中。有人可能会认为只需要返回假的响应对象就够了,没必要缓存它。但这样会因响应对象被系统释放而导致appcrash。不知道为何为会这样,可能是iOS的bug(MacOSX10.5.x也存在同样问题,而10.4.x及更早的系统上没有问题),也可能是URLLoadingSystem内部类之间的依赖所致。所以我们先缓存响应对象。确保所有响应都是真实存在于缓存中,这也iOS希望的,最重要的是不会crash.更新:因为假的响应是以大于0的大小来初始化的,看起来结缓存它也是必要的。2.创建新的缓存:接下来需要创建一个新的缓存并告诉iOS系统使用新的缓存代替默认的,这样当URLLoadingSystem检测资源缓存时才会调用上面的代码。这要在任意UIWebView开始加载页面前做,显然应该放在app启动的时候:1.NSString*path=...//thepathtothecachefile2.NSUIntegerdiscCapacity=10*1024*1024;3.NSUIntegermemoryCapacity=512*1024;4.FilteredWebCache*cache=5.[[FilteredWebCachealloc]initWithMemoryCapacity:memoryCapacity6.diskCapacity:discCapacitydiskPath:path];7.[NSURLCachesetSharedURLCache:cache];8.[cacherelease];这里需要提供一个缓存存储路径。缓存文件由NSURLCache对象自动生成,我们无需事先创建文件,但要定义缓存文件所存位置(必须是应用程序“沙盒”内,如“tmp”目录或是“Document”目录)这就是实现UIWebView基于URL进行请求过滤的所有内容,看起来其实并不复杂注:如果过滤规则在app运行过程中会改变,你需要从缓存中删除假的响应。NSURLCache提供了删除方法,所以这不是问题。如果过滤规则不会改变,则无需关心【编辑推荐】1.就一张图看懂iOS学习流程2.说说iOS与内存管理(上)3.11个超棒的iOS开发学习网站

1、当您付费下载文档后,您只拥有了使用权限,并不意味着购买了版权,文档只能用于自身使用,不得用于其他商业用途(如 [转卖]进行直接盈利或[编辑后售卖]进行间接盈利)。
2、本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供参考,付费前请自行鉴别。
3、如文档内容存在侵犯商业秘密、侵犯著作权等,请点击“举报”。

常见问题具体如下:

1、问:已经付过费的文档可以多次下载吗?

      答:可以。登陆您已经付过费的账号,付过费的文档可以免费进行多次下载。

2、问:已经付过费的文档不知下载到什么地方去了?

     答:电脑端-浏览器下载列表里可以找到;手机端-文件管理或下载里可以找到。

            如以上两种方式都没有找到,请提供您的交易单号或截图及接收文档的邮箱等有效信息,发送到客服邮箱,客服经核实后,会将您已经付过费的文档即时发到您邮箱。

注:微信交易号是以“420000”开头的28位数字;

       支付宝交易号是以“2024XXXX”交易日期开头的28位数字。

客服邮箱:

biganzikefu@outlook.com

所有的文档都被视为“模板”,用于写作参考,下载前须认真查看,确认无误后再购买;

文档大部份都是可以预览的,笔杆子文库无法对文档的真实性、完整性、准确性以及专业性等问题提供审核和保证,请慎重购买;

文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为依据;

如果您还有什么不清楚的或需要我们协助,可以联系客服邮箱:

biganzikefu@outlook.com

常见问题具体如下:

1、问:已经付过费的文档可以多次下载吗?

      答:可以。登陆您已经付过费的账号,付过费的文档可以免费进行多次下载。

2、问:已经付过费的文档不知下载到什么地方去了?

     答:电脑端-浏览器下载列表里可以找到;手机端-文件管理或下载里可以找到。

            如以上两种方式都没有找到,请提供您的交易单号或截图及接收文档的邮箱等有效信息,发送到客服邮箱,客服经核实后,会将您已经付过费的文档即时发到您邮箱。

注:微信交易号是以“420000”开头的28位数字;

       支付宝交易号是以“2024XXXX”交易日期开头的28位数字。

笔杆子文秘
机构认证
内容提供者

为您提供优质文档,供您参考!

确认删除?