iOS UIWebView URL拦截
http://www.cocoachina.com/ios/20150626/12161.html
本文译者:candeladiao,原文:URL filtering for UIWebView on the iPhone
说明:译者在做app开发时,因为页面的javascript文件比较大导致加载速度很慢,所以想把javascript文件打包在app里,当UIWebView需要加载该脚本时就从app本地读取,但UIWebView并不支持加载本地资源。最后从下文中找到了解决方法,第一次翻译,难免有误,大家多多指教。
iCab Mobile(一款iOS平台的网页浏览器)要实现一个拦截管理器来过滤页面上的广告及其他东西。它有一个简单的基于URL过滤规则的列表(通常由用户维护),当页面包含的资源(图片、js以及css等),文件的URL存在于规则列表中时,资源就不会被加载。
但看一下UIWebView类的API,会发现我们没有办法知道UIWebView正在加载什么资源,更糟的是,当你希望过滤掉某些资源文件的时候,没有方法可以强制UIWebView不去加载这些文件,
拦截器看起来貌似没有可能实现。
当然还是有解决方案的,否则这篇文件就没什么卵用。
正如上面所说,实现拦截器不能靠UIWebView,因为UIWebView没有提供任何有用的API。
对UIWebView的所有请求,要找到一个能中断所有HTTP 请求的切入点,我们需要先了解一下Cocoa的URL Loading System,因为UIWebView是使用URL Loading System从web端取数据的。我们需要的切入点NSURLCache类就是URL Loading System的一部分。虽然目前iOS系统不会在磁盘上缓存任何数据(后面的iOS系统版本或许会有不同),因此在UIWebView开始加载前,NSURLCache管理的缓存数据通常为空,但UIWebView仍然会检测所请求资源文件是否存在于缓存。所以我们需要做的只是继承NSURLCache并重载其方法:
1
|
- (NSCachedURLResponse*)cachedResponseForRequest:(NSURLRequest*)request |
UIWebView请求所有资源时都会调用这个方法。因为我们只需要在这个方法里判断请求的URL是否是我们想拦截的。如果是则创建一个没有内容的假response,否则只需调用super方法即可。
如下是实现细节:
1.继承NSURLCache:
FilteredWebCache.h:
1
2
3
4
|
@interface FilteredWebCache : NSURLCache { } @end |
子类的主要代码
FilteredWebCache.m:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#import "FilteredWebCache.h" #import "FilterManager.h" @implementation FilteredWebCache - (NSCachedURLResponse*)cachedResponseForRequest:(NSURLRequest*)request { NSURL *url = [request URL]; BOOL blockURL = [[FilterMgr sharedFilterMgr] shouldBlockURL:url]; if (blockURL) { NSURLResponse *response = [[NSURLResponse alloc] initWithURL:url MIMEType:@ "text/plain" expectedContentLength:1 textEncodingName:nil]; NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:[NSData dataWithBytes: " " length:1]]; [ super storeCachedResponse:cachedResponse forRequest:request]; [cachedResponse release]; [response release]; } return [ super cachedResponseForRequest:request]; } @end |
首先判断URL是否需拦截(判断通过FilterManager类实现,类实现在此不列出)。如果需要,创建一个无内容的响应对象并把它存在cache中。有人可能会认为只需要返回假的响应对象就够了,没必要缓存它。但这样会因响应对象被系统释放而导致app crash。不知道为何为会这样,可能是iOS的bug(Mac OS X 10.5.x也存在同样问题,而10.4.x及更早的系统上没有问题),也可能是URL Loading System内部类之间的依赖所致。所以我们先缓存响应对象。确保所有响应都是真实存在于缓存中,这也iOS希望的,最重要的是不会crash.
更新:因为假的响应是以大于0的大小来初始化的,看起来结缓存它也是必要的。
2.创建新的缓存:
接下来需要创建一个新的缓存并告诉iOS系统使用新的缓存代替默认的,这样当URL Loading System检测资源缓存时才会调用上面的代码。这要在任意UIWebView开始加载页面前做,显然应该放在app启动的时候:
1
2
3
4
5
6
7
8
|
NSString *path = ... // the path to the cache file NSUInteger discCapacity = 10*1024*1024; NSUInteger memoryCapacity = 512*1024; FilteredWebCache *cache = [[FilteredWebCache alloc] initWithMemoryCapacity: memoryCapacity diskCapacity: discCapacity diskPath:path]; [NSURLCache setSharedURLCache:cache]; [cache release]; |
这里需要提供一个缓存存储路径。缓存文件由NSURLCache对象自动生成,我们无需事先创建文件,但要定义缓存文件所存位置(必须是应用程序“沙盒”内,如“tmp”目录或是“Document”目录)
这就是实现UIWebView基于URL进行请求过滤的所有内容,看起来其实并不复杂
注:如果过滤规则在app运行过程中会改变,你需要从缓存中删除假的响应。NSURLCache提供了删除方法,所以这不是问题。如果过滤规则不会改变,则无需关心
iOS UIWebView URL拦截的更多相关文章
- ios UIWebView截获html并修改便签内容(转载)
ios UIWebView截获html并修改便签内容 博客分类: iphone开发iphone开发phoneGap uiwebviewstringByEvaluatingJavaScriptFromS ...
- IOS UIWebView截获html并修改便签内容,宽度自适应
需求:混合应用UIWebView打开html后,UIWebView有左右滚动条,要去掉左右滚动效果: 方法:通过js截获UIWebView中的html,然后修改html标签内容: 实例代码: 服 ...
- ios UIWebView截获html并修改便签内容
需求:混合应用UIWebView打开html后,UIWebView有左右滚动条,要去掉左右滚动效果: 方法:通过js截获UIWebView中的html,然后修改html标签内容: 实例代码: 服务器端 ...
- iOS UIWebView获取403/404
问题描述 与WindowsPhone不同,iOS UIWebView并不认为403/404这种情况下页面访问是失败的,这也情有可原,但有时候,我们需要对WebView所遇到的403/404进行处理. ...
- iOS UIWebView与JavaScript的交互 相关资料
UIWebView自适应宽度 iOS UIWebView中javascript与Objective-C交互.获取摄像头 iOS中JavaScript和OC交互 iOS与js交互,获取webview完整 ...
- iOS根据Url 获取图片尺寸
iOS根据Url 获取图片尺寸 // 根据图片url获取图片尺寸 +(CGSize)getImageSizeWithURL:(id)imageURL { NSURL* URL = nil; if([i ...
- Shiro第一篇【Shiro的基础知识、回顾URL拦截】
Shiro基础知识 在学习Shiro这个框架之前,首先我们要先了解Shiro需要的基础知识:权限管理 什么是权限管理? 只要有用户参与的系统一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安 ...
- Shiro入门这篇就够了【Shiro的基础知识、回顾URL拦截】
前言 本文主要讲解的知识点有以下: 权限管理的基础知识 模型 粗粒度和细粒度的概念 回顾URL拦截的实现 Shiro的介绍与简单入门 一.Shiro基础知识 在学习Shiro这个框架之前,首先我们要先 ...
- iOS UIWebView 获取内容实际高度,关闭滚动效果
本文转载至 http://my.oschina.net/Khiyuan/blog/341535 iOS UIWebView 获取内容实际高度,关闭滚动效果 近期做东西,将 UIWebView 嵌套 ...
随机推荐
- copyTo和clone的区别/制作mask的fillpoly函数(有问题)
OpenCV中mat::copyto( )函数使用方法 OpenCV的fillPoly函数 使用OpenCV库进行图像处理时,经常会用到clone和copyTo函数,这里对两个函数进行介绍. copy ...
- [Array]628. Maximum Product of Three Numbers
Given an integer array, find three numbers whose product is maximum and output the maximum product. ...
- CF 529B Group Photo 2 (online mirror version)
传送门 解题思路 这道题要用到贪心的思路,首先要枚举一个h的最大值,之后check.如果这个东西的w[i]与h[i]都大于枚举的值就直接return false,如果w[i]比这个值小,h[i]比这个 ...
- TZ_02MyBatis_一级缓存和二级缓存
1.Mybatis中的缓存 1>什么是缓存 存在于内存中的临时数据. 2> 为什么使用缓存 减少和数据库的交互次数,提高执行效率. 3>什么样的数 ...
- applyMiddleware源码中的闭包
闭包都是个老掉牙的话题了,这次又提起,是因为重看Redux源码时发现了applyMiddleware里的用法很巧妙.我们先看一个简单的例子. var a = (num) => num + 1 v ...
- hdu 3068 最长回文(manacher入门)
最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- c#通过app.manifest使程序以管理员身份运行
通常我们使用c#编写的程序不会弹出这个提示,也就无法以管理员身分运行.微软的操作系统使用微软的产品方法当然是有的,通过app.manifest配置可以使程序打开的时候,弹出UAC提示需要得到允许才可以 ...
- .net core/.net 使用 CommandLineParser 来标准化地解析命令行
CommandLineParser 是一款用于解析命令行参数的 NuGet 包.你只需要关注你的业务,而命令行解析只需要极少量的配置代码. 本文将介绍如何使用 CommandLineParser 高效 ...
- JavaScript--放大镜
上例图: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF- ...
- PPT转PDF
需求:可以上传ppt,前台可以预览. 在用程序将ppt转pdf的过程中,遇到几个问题,记录如下: 1.检索 COM 类工厂中 CLSID 为 {91493441-5A91-11CF-8700-00AA ...