iOS奇淫技巧 —— 解决UIWebView重定向后,JSCon
问题:UIWebview重定向后,JSContext 注入的模型丢失问题
现象:js无法调起原生
我遇到这个问题之后,也是谷歌百度了很久很久。
github
找到一个开源项目
UIWebViewTS_JavaScriptContet
拉下来之后,只需要这样就解决问题了
然后,有循环引用?
行,那这样好了,注入模型
8F657EFC-C0C1-498F-BA81-9089E6428D53.png
ok,现在来简单分析一下是如何解决这个问题的。
其中,最关键的是一个回调方法
didCreateJavaScriptContext
作者通过 runtime 机制,巧妙地在 JavaScriptContext 创建之后,生成回调。然后在回调中我们注入mode
,使其生效。重定向之后,重新生成context后再次回调这个方法,重新注入mode
,重新生效。
详细各位可以看 UIWebViewTS_JavaScriptContet 中 UIWebView+TS_JavaScriptContext.m 源码
当我以为完美地解决了这个问题时,才发现这是一个坑啊!
他用了私有API,已有不少朋友深受其害。。。
AFA0A099-9C89-449B-9B0C-92BDFEDC630A.png当我无计可施的时候,在一个不起眼的答案中找到了解决思路,也正是本文要说的奇淫技巧。。
http://stackoverflow.com/questions/22714373/easyjswebview-breaks-when-reloading-the-webview
作者提出的是 EasyJSWebView
的一个崩溃问题
网友给出的解决办法是将原来的UIWebView移除,重新生成一个UIWebView替换掉
针对我的问题,本着试一试的想法写出了如下代码:
1BE8AE9C-47F1-4883-8BC5-F6A3A33FBACF.png
重新生成了一个 UIWebView
结果问题解决了!
有个缺点就是,没有了历史记录,不能使用 back
了!需要手动处理 返回,而且没有缓存了。
对于我们的业务,这些问题都还不算问题,所以也算是一个可以采用的解决方式。
分析
为什么我重新创建一个 UIWebView
再注入模型就可以了呢??
网上看到一位coder
的猜测
- H5 一级页面的时候,是 webView 第一次创建,在 webView loadRequest 之前,内存已经 creat JavaScriptContext,也就说 在 UIWebViewDelegate 回调发生之前。
- 而跳转到二级页面,页面只是 再次 回调 UIWebViewDelegate ,这个时候,JavaScriptContext creat时机可能会晚于 - (BOOL)webView: shouldStartLoadWithRequest:navigationType: 也就是说回调发生的时候,新的 JavaScriptContext还未创建。
问题的关键是,我们注入模型的时机必须在创建 JavaScriptContext
与 JS调用 之间。