ios wkweb设置图片_iOS WKWebView (NSURLProtocol)拦截js、css,图片资源

项目地址github:HybirdWKWebVIew

HybridNSURLProtocol

一个基于WKWebView的hybirde的容器。能拦截所有WKWKWebView的的css,js,png等网络请求的demo

NSURLProtocol 子类,就可以对 app 内所有的网络请求进行:

[NSURLProtocol registerClass:[HybridNSURLProtocol class]]

可是在 WKWebView 中的请求却完全不遵从这一规则,只是象征性+ (BOOL) canInitWithRequest:(NSURLRequest *)request 方法,之后的整个请求流程似乎就与 NSURLProtocol 完全无关了。

使我WKWebView 的一度认为请求不遵守NSURLProtocol协议,所以不走 NSURLProtocol。这个也是很苦扰我的问题。导致我们hybird的容器1.0也是是用UIWebVIew实现的。

但在苹果放在gittub的CustomHTTPProtocol,明显感觉到WKWebview的也是遵守NSURLProtocol,要不也不会走+ (BOOL)canInitWithRequest:(NSURLRequest *)request;后来一个每天看博客和gittub的习惯帮助了我,找到一个大神的不久前开源库。

使用了WKBrowsingContextController和registerSchemeForCustomProtocol。 通过反射的方式拿到了私有的 class/selector。通过kvc取到browsingContextController。通过把注册把 http 和 https 请求交给 NSURLProtocol 处理。

[NSURLProtocol wk_registerScheme:@"http"];

[NSURLProtocol wk_registerScheme:@"https"];

下面直接上源代码吧

//FOUNDATION_STATIC_INLINE 属于属于runtime范畴,你的.m文件需要频繁调用一个函数,可以用static inline来声明。在SDWebImage读取内存的缓存也用到这个声明。

FOUNDATION_STATIC_INLINE Class ContextControllerClass() {

static Class cls;

if (!cls) {

cls = [[[WKWebView new] valueForKey:@"browsingContextController"] class];

}

return cls;

}

FOUNDATION_STATIC_INLINE SEL RegisterSchemeSelector() {

return NSSelectorFromString(@"registerSchemeForCustomProtocol:");

}

FOUNDATION_STATIC_INLINE SEL UnregisterSchemeSelector() {

return NSSelectorFromString(@"unregisterSchemeForCustomProtocol:");

}

@implementation NSURLProtocol (WebKitSupport)

+ (void)wk_registerScheme:(NSString *)scheme {

Class cls = ContextControllerClass();

SEL sel = RegisterSchemeSelector();

if ([(id)cls respondsToSelector:sel]) {

// 放弃编辑器警告

#pragma clang diagnostic push

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

[(id)cls performSelector:sel withObject:scheme];

#pragma clang diagnostic pop

}

}

+ (void)wk_unregisterScheme:(NSString *)scheme {

Class cls = ContextControllerClass();

SEL sel = UnregisterSchemeSelector();

if ([(id)cls respondsToSelector:sel]) {

// 放弃编辑器警告

#pragma clang diagnostic push

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

[(id)cls performSelector:sel withObject:scheme];

#pragma clang diagnostic pop

}

}

注册后,客户端所有请求走+ (BOOL)canInitWithRequest:(NSURLRequest *)request。下面是打印的请求的log

+ (BOOL)canInitWithRequest:(NSURLRequest *)request

{

NSLog(@"request.URL.absoluteString = %@",request.URL.absoluteString);

NSString *scheme = [[request URL] scheme];

if ( ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||

[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame ))

{

//看看是否已经处理过了,防止无限循环

if ([NSURLProtocol propertyForKey:KHybridNSURLProtocolHKey inRequest:request])

return NO;

return YES;

}

return NO;

}

Aaron Swartz

request的重写定向,request的重写定向,替换百度知道的log

+ (BOOL)canInitWithRequest:(NSURLRequest *)request

{

NSLog(@"request.URL.absoluteString = %@",request.URL.absoluteString);

NSString *scheme = [[request URL] scheme];

if ( ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||

[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame ))

{

//看看是否已经处理过了,防止无限循环

if ([NSURLProtocol propertyForKey:KHybridNSURLProtocolHKey inRequest:request])

return NO;

return YES;

}

return NO;

}

这里最好加上缓存判断,加载本地离线文件, 这个直接简单的例子。

- (void)startLoading

{

NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];

//给我们处理过的请求设置一个标识符, 防止无限循环,

[NSURLProtocol setProperty:@YES forKey:KHybridNSURLProtocolHKey inRequest:mutableReqeust];

//这里最好加上缓存判断,加载本地离线文件, 这个直接简单的例子。

if ([mutableReqeust.URL.absoluteString isEqualToString:sourIconUrl])

{

NSData* data = UIImagePNGRepresentation([UIImage imageNamed:@"medlinker"]);

NSURLResponse* response = [[NSURLResponse alloc] initWithURL:self.request.URL MIMEType:@"image/png" expectedContentLength:data.length textEncodingName:nil];

[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];

[self.client URLProtocol:self didLoadData:data];

[self.client URLProtocolDidFinishLoading:self];

}

else

{

NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];

self.task = [session dataTaskWithRequest:self.request];

[self.task resume];

}

}

下面是代码效果图

WechatIMG1.png

WechatIMG2.jpeg

项目地址:

github:HybirdWKWebVIew,对您有帮助,欢迎star。

有问题反馈

在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

github:LiuShuoyu

接受启发的作者的github

github:Yeatse CC

苹果开发者文档:apple

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/288106.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

solr的空间查询(查询地图周围坐标)

原文网址:http://www.cnblogs.com/hanhuibing/articles/5680616.html 基于Solr的空间搜索 如果需要对带经纬度的数据进行检索,比如查找当前所在位置附近1000米的酒店,一种简单的方法就是:获取数据库中的所有酒店数据,…

「零门槛多语言 Python/C/C# 通用思想学习系列」第一篇:经典HelloWorld

环境说明 操作系统:Windows7 SP1 编辑器说明: Python:notepadC:devcC sharp(C#):Visual Studio2019 注意: 标点:在编程中要使用英文的标点符号,必须切记数…

c# 元组类型

简介元组就是将一组松散的对象简单地组合在一起。元组比数组灵活性略强,数组中元素类型是统一的,而元组使用的是泛型参数,每个元素类型相互独立。元组不同于类和结构,类和结构是高度聚合的数据类型,其中要实现各种复杂…

服务器2008 系统日志 提示打印机,介绍服务器日志出现打印机错误的解决方法

今天来聊聊一篇关于服务器日志出现打印机错误的解决方法的文章,现在就为大家来简单介绍下服务器日志出现打印机错误的解决方法,希望对各位小伙伴们有所帮助。windows2003日志提示,打印机 ****未知。登录之前,请与管理员联系,安装驱动程序。事…

js 错误/异常处理

为什么80%的码农都做不了架构师?>>> /*** 自定义错误处理*/ onerror handleError; function handleError(desc,page,line){alert("desc:"desc"\n""page:"page"\n""line:"line); } var s null; s.t…

多面体 (Multipatch)

多面体要素是一种可存储面集合的 GIS 对象,能够在数据库中将 3D 对象的边界表示为单个行。面可存储表示要素组成部分的纹理、颜色、透明度和几何信息。面中存储的几何信息可以是三角形、三角扇、三角条带或环,如下所示。 所有多面体都将…

剑指offer之二叉搜索树的第K个节点

1 问题 给定一颗二叉搜索树,请找出其中的第k小的结点。例如, 5 3 7 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。 2 分析 二叉树定义:二叉查找树(Binary Search Tree),&#xff0…

Python turtle库实现基本剖析

有关turtle的相关使用请参考《python图形绘制库turtle中文开发文档及示例大全》 本篇文为turtle库的实现剖析,但不涉及 python 的 TK库。 开始 入口探寻 在turtle中,直走是使用 forward 或者 fd 函数;在本机安装好了 turtle 库后&#xf…

git菜单形式的_Idea:Git的常用菜单操作和常用命令

工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下:假设小组中有两个人,组长小张,组员小袁场景一:小张创建项目并提交到远程Git仓库场景二:小袁从远程Git仓库上获取项目源码场景三:小…

分享我做Dotnet9博客网站时积累的一些资料

从2019年使用WordPress搭建Dotnet9网站,到现在手撸代码开发,介绍中间使用的一些资源,绝无保留,希望对大家有用。1. 申请域名、搭建WordPress网站时间点:2019年11月申请Dotnet9域名,讲个实话,站长…

css媒体查询改变上边距,CSS媒体查询宽度或高度

我在一个全屏页面的中心放置了一个徽标。img.logo {width: 920px;height: 552px;position: absolute;top: 50%;left: 50%;margin-left: -460px;margin-top: -276px;}这很好用。现在我想在不同的设备高度和宽度上使用不同的尺寸,所以我尝试使用媒体查询。media (max-…

基于Azure Blob冷存储的数据压缩备份总结

基于上一篇的压缩算法对比分析报告,选择了LZ4算法的普通模式,其测试压缩率为28%,20G压缩时间为256s,估计1T的冷备时间为3.5h。 接下来,将23T的HBase历史数据进行了压缩冷备,压缩后大小为3.5T,冷…

Ubuntu使用VNC运行基于Docker的桌面系统

2019独角兽企业重金招聘Python工程师标准>>> docker-ubuntu-vnc-desktop From Docker Index docker pull dorowu/ubuntu-desktop-lxde-vnc Build yourself git clone https://github.com/fcwu/docker-ubuntu-vnc-desktop.git docker build --rm -t dorowu/ubuntu-de…

【ArcGIS风暴】ArcGIS个人数据库(.mdb)中矢量字段(如Shape_Length、Shape_Area)无法删除的解决办法

ArcGIS中,某些操作,比如空间连接(Spatial Join)结果属性表中会自动产生Shape_Length和Shape_Area字段,这些字段无法删除,如下: 即使在工具箱中的【删除字段】工具,也找不到这些字段,如图所示,给我们的数据入库工作带来了一定的困扰。 解决思路: mdb是个人数据库,基…

excel导入 HSSFWorkbook和XSSFWorkbook

excel导入 excel版本有03版本和07版本的区别,文件后缀名分别为.xls和.xlsx。它们对应的POI中的Workbook也是不同的,分别是HSSFWorkbook和XSSFWorkbook; 对于不同版本的EXCEL文档要使用不同的工具类,如果使用错了,会提示…

python thinker canvas create_arc 使用详解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/A757291228/article/details/106739556 ———————————————— 版权声明:本文…

剑指offer之二叉搜索树和双向链表

1 问题 比如我们搜索二叉树如下,我们需要变成双向链表 2 分析 我们知道这个变成双向链接的时候是按照树的中序遍历打印的,我们只需要在中序遍历打印的时候操作该节点,我们可以用临时变量保存这个节点,同时我们也需要单独增加一…

text 热敏打印机_只要有想象力,打印机都能做游戏

不知道为什么,文本冒险游戏最近频频被人提及。这不,现在又出来一个基于实时打印的文本冒险游戏 —— Quest Smith。这位脑洞较大的创客名叫 Bekir Dağ ,他用微型打印机和树莓派做出了这个手持游戏设备。关于文本冒险游戏的背景知识&#xff…

C#内建接口:IConvertible

这节来讲一个比较有意思的接口:IConvertible。IConvertible接口处于System.Runtime命名空间下,这个接口规定了一批ToXxx()方法,凡是实现了这个接口的方法,我们都可以尝试将其转换为自己想要的类型。IConvertible中有什么&#xff…

ArcGIS升级地理数据库

本博文教大家如何快速地将低版本地理数据库升级为高版本地理数据库。 方法一:使用“升级地理数据库”工具箱二、使用ArcCatalog地理数据库→右键→属性。三、创建不同版本的地理数据库