让WKWebView支持NSURLProtocol

NSURLProtocol能够拦截UIWebView内所有的请求,但是WKWebView 中的请求却完全不遵从这一规则,只是象征性调用canInitWithRequest方法,之后的整个请求流程似乎就与 NSURLProtocol 完全无关了。使我一度认为WKWebView请求不遵守NSURLProtocol协议。

其实是能够做到的,因为WKWebView没有开放相关的API,所以我们需要使用私有API调用来实现。使用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
}
}

注册后,WKWebView内的请求也会走canInitWithRequest方法了。

转载:https://www.jianshu.com/p/4fc13d4d5607

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

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

相关文章

java8新特性(3)--- 函数式接口

java8新特性(3)— 函数式接口 有且仅有一个抽象方法 package com.common.jdk8;import java.util.Arrays; import java.util.List; import java.util.function.Predicate;// 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,…

Git仓库迁移,包括所有的分支、标签、日志

仅三行命令即可完成: git clone --bare http://域名/分组/仓库名称.git cd 仓库名称.git git push --mirror http://新域名/新分组/新仓库名称.git

java8新特性(4)— Stream流

java8新特性(4)— Stream流 遍历集合更强大 package com.common.jdk8;import java.util.*; import java.util.stream.Collectors;//Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。 //Stream 使用一种类似用…

二、工作量证明链-区块链技术的雏形

用算法解决难题——区块链技术的雏形 构造出一个完美的、可以解决问题的“拜占庭容错系统”是一个不小的挑战。而且构造出来以后,其是否真的有效,能否经得起时间的考验与各方的质疑,这些都关乎着这个系统未来的命运与其创造群体的声誉。 2008…

CocoaPods通过网络代理执行资源更新

一、使用网络代理 首先在电脑设置网络代理配置。 二、设置git的http、https代理 1.查看git是否已经设置网络代理 首先可以先查本地的git配置有没有配置http/https代理:git config --global -e 如果没有看到 [http]proxy和 [https]proxy就代表没有设置http/http…

java8新特性(5)— Optional 类

java8新特性(5)— Optional 类 空指针解决方案 package com.common.jdk8;import java.util.Optional;//Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。 //Optional 是个容器&…

五、工作量证明链解决拜占庭将军问题之模拟程序(Objective-C)

一、概述: 此程序用来模拟工作量证明链如何解决拜占庭将军问题,使用Objective-C语言,需要使用Xcode开发工具运行并执行演示,演示结果打印在Xcode控制台。 二、示例程序: 程序下载地址:工作量证明链解决拜…

java8新特性(6)— 日期与时间

java8新特性(6)— 日期与时间 全新的日期与时间处理 package com.common.jdk8;import java.time.*;//Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。 //在旧版的 Java 中,日期时间 API 存在诸多问题&#xff…

六、区块链主流共识算法浅析

转自:http://www.cocoachina.com/cms/wap.php?actionarticle&id22240。 一、概述: 1.工作量证明(Proof of Work): 通过所有节点的工作量竞争来达成一致。竞争的是运算力。 2.权益证明(Proof of S…

java8新特性(7)— Base64

java8新特性(7)— Base64 新增Base64工具类 package com.common.jdk8;import java.io.UnsupportedEncodingException; import java.util.Base64; import java.util.UUID;//在Java 8中,Base64编码已经成为Java类库的标准。 //Java 8 内置了 …

修改git历史提交的commit信息

本文是基于idea的操作,亲测可用 前言: 很多公司都会自定义 Git - 使用强制策略,那么他的commit信息就会有固定的格式,一旦不是这个格式,就会出现push失败 但是push失败,很多也只在dev和master分支做强制限…

七、区块链如何运用merkle tree验证交易真实性

转载自:https://www.tangshuang.net/4117.html 本文假设你已经知道区块链中merkle tree的原理,现在搞明白具体怎么来实现交易真实性验证。 Merkle Tree 这个小节简述一下merkle的原理。简单说,merkle tree就是一个hash二叉树,父…

idea端口占用解决记录

idea端口占用解决 每次占用,每次都要百度,路子很清晰了,记录下 报错:The port may already be in use or the connector may be misconfigured. 解决: 1.cmd 2.netstat -ano|findstr 你的端口号 举例:…

西安软件行业闲谈

尘埃落定,最终选择了西安 讲真,今年年初,就萌生了回西安的想法,毕竟北漂几年,该回了 当初还想着去上海两年,再去深圳两年,好好体验下各个一线城市的不同魅力 性格就是这样,不甘平凡…

消息队列(1):一个消息队列应该有的特点

消息队列常见场景 异步解耦 削峰填谷 日志收集分析 代替事务,最终一致 消息队列特点 消息队列之所以能异步,就是因为消息并不是实时处理的,那肯定会有一个存储消息,处理消息的地方,才能达到异步效果。 所以最简单的…

消息队列(2):常见的消息队列协议

协议很常见,只要是通信,就会用到协议,就像我们说话的语言一样,不同的语言连通着不同的人群。 所以说,消息队列也是一样,想要互相通信,就要使用同一种协议。 每个协议下的消息队列,都…

spingboot下shiro自定义过滤器roles

shiro默认的roles过滤,是与的关系,就是你的用户得有roles对应的所有角色,才算有权限。 但是实际开发过程中,更多的是或的需求,只要用户满足roles中的一个角色,就算有权限。 所以就涉及到重写过滤器roles&am…

shiro的集群动态权限更新

shiro的动态权限,一般都是将权限放在数据库中,项目启动后将权限加载给shiro 当数据库的权限数据发生改变时,重新加载权限给shiro。 单机这样做没问题,但是当项目服务是集群的时候,比如有tomcat1,tomcat2&am…

消息队列(3):RabbitMQ

RabbitMQ,基于AMQP协议实现。 特点: 消息可靠:持久化消息,传输确认,发布确认。 路由灵活:使用AMQP的Exchange来路由消息,包括RabbitMQ内置的Exchange,还有复杂的路由也可以使用多个…

java基础 --- Arrays.asList():返回指定数组支持的固定大小列表

Arrays.asList():返回指定数组支持的固定大小列表 首先看下这个方法的源码注释,注意第一句,Returns a fixed-size list backed by the specified array., 意思就是:返回指定数组支持的固定大小列表 所以:…