`
啸笑天
  • 浏览: 3465625 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

iOS UIWebView URL拦截

    博客分类:
  • ios
 
阅读更多

本文译者: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提供了删除方法,所以这不是问题。如果过滤规则不会改变,则无需关心

 

from http://www.cocoachina.com/ios/20150626/12161.html

 

 

 

分享到:
评论

相关推荐

    iOS UIWebView URL拦截.pdf

    总之,通过自定义NSURLCache子类并在其中实现URL拦截逻辑,开发者可以控制UIWebView加载特定资源的行为。这种方式虽然略微复杂,但为解决特定问题提供了一种有效途径。对于性能优化和用户体验的提升,这样的定制化...

    iOS UIWebView的缓存

    通过创建一个自定义的URLProtocol子类,我们可以拦截并处理所有的网络请求,从而实现更精细的缓存策略。 4. **离线模式下的加载**: 当没有网络连接时,我们需要手动检查UIWebView是否可以从缓存中加载页面。可以...

    iOS和H5页面交互拦截

    在iOS应用中,我们通常使用UIWebView或WKWebView来加载和显示HTML内容。这两个控件提供了JavaScriptCore框架,它允许我们在Objective-C或Swift代码中执行JavaScript,并获取JavaScript的返回值。 标题“iOS和H5页面...

    iOS-UIWebview缓存并保证实时性

    为了解决这个问题,我们可以创建一个自定义的URLProtocol,名为ZFJCacheURLProtocol,来拦截和处理UIWebView的所有请求。自定义URLProtocol的步骤如下: 1. 遵循URLProtocol协议:首先,你需要创建一个新的类并让它...

    iOS开发之UIWebView

    在iOS开发中,UIWebView是苹果提供的一种原生控件,用于在应用程序内展示网页内容。这个组件允许开发者集成Web应用与本地应用的功能,提供了一种混合开发的解决方案。这篇博客文章“iOS开发之UIWebView”可能详细...

    iOS和JS的交互之在代理方法拦截Url,识别判断

    本文将深入探讨如何在代理方法中拦截URL,以实现iOS和JS之间的有效通信。首先,我们需要理解iOS中的WKWebView组件,它是苹果提供的用于加载和呈现Web内容的工具,它支持与JavaScript的深度集成。 ### WKWebView简介...

    IOS--UIWebView加载进度条(NJKWebViewProgress)

    本教程将围绕"IOS--UIWebView加载进度条(NJKWebViewProgress)"这一主题进行讲解。 NJKWebViewProgress 是一个开源库,由Nick Jones(njkolko)开发,它为UIWebView提供了加载进度条的功能。这个库通过拦截请求和...

    网页视图 UIWebView

    总结起来,UIWebView是iOS开发中的一个重要组件,它允许我们在应用程序内嵌入网页内容,通过处理URL字符串、利用其属性和协议,可以实现丰富的交互功能。尽管有新的替代品,但理解UIWebView的工作原理和使用方式对于...

    UIWebViewDemo

    此外,`UIWebView`支持JavaScript与Objective-C之间的交互,通过实现`UIWebViewDelegate`的`webView:shouldStartLoadWithRequest:navigationType:`方法,可以拦截页面加载请求并进行处理,甚至执行自定义的行为。...

    iPhone开发之UIWebView示例程序

    (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType`方法,我们可以监听JavaScript的请求,并在需要的时候拦截或...

    iOS oc拦截网页wkwebview视频内容 的demo

    WKWebView是苹果提供的一个高级组件,用于在iOS应用中渲染网页,它相比UIWebView有更高的性能和更好的内存管理。 1. **WKWebView介绍**: - WKWebView是WebKit框架的一部分,提供了与WebKit引擎的接口,用于显示...

    UIWebView缓存网页

    首先,我们需要了解iOS的URL Loading System,这是一个强大的网络请求框架,UIWebView就是基于此系统来加载网页的。系统默认会进行一定的缓存处理,但这种缓存机制对于离线浏览可能并不足够。为了解决这个问题,我们...

    详解如何拦截iOS所有网络请求

    iOS 网络请求拦截详解 iOS 平台上的网络请求拦截是移动应用开发中的一项重要技术。通过拦截网络请求,可以实现统计所有的网络请求,了解应用程序的网络行为,从而优化应用程序的性能和用户体验。在本文中,我们将...

    ios 内嵌浏览器

    UIWebView是苹果提供的一种组件,它允许开发者在iOS应用中嵌入一个浏览器控件,使得用户可以在应用程序内部浏览网页。这篇内容我们将深入探讨如何在iOS应用中使用UIWebView以及它的相关知识点。 首先,UIWebView是...

    iOS11 WKWebView 无法加载内容的解决方法

    WKWebView 是 iOS 中的一个网页视图控件,自 iOS 8 开始引入,取代了 UIWebView。WKWebView 提供了更好的性能和安全性,但是在 iOS 11 中,却出现了加载内容失败的问题。本文将介绍 iOS 11 WKWebView 无法加载内容的...

    iOS和JS交互教程之WKWebView-协议拦截详解

    在iOS端,我们需要实现WKWebView的代理方法`webView:decidePolicyForNavigationAction:decisionHandler:`来拦截特定的URL请求: ```swift // WKNavigationDelegate func webView(_ webView: WKWebView, ...

    ios webView获取高度

    总结,`ios webView获取高度`涉及到UIWebView的使用、JavaScript与原生代码的交互以及自适应布局的策略。正确理解和运用这些知识点,能帮助开发者构建更强大的混合型iOS应用。在实际开发中,还需要注意性能优化,如...

    ios webView获取html标签

    在iOS开发中,`UIWebView` 是一个非常重要的组件,用于在应用内展示网页内容。在某些场景下,我们可能需要获取`UIWebView`中加载的HTML页面的特定标签,以便进行进一步的操作,如解析数据、修改样式或者处理链接。本...

    UIWebView高级应用

    在iOS开发中,UIWebView是苹果提供的一种非常重要的组件,用于在应用程序内嵌入网页内容。这个组件使得开发者能够展示HTML、CSS和JavaScript等Web技术创建的页面,从而实现丰富的交互性和动态性。本篇文章将深入探讨...

Global site tag (gtag.js) - Google Analytics