引: 以前做项目的时候也做过webview和js交互,以为会手到擒来。结果WTFK、两天的时间来研究它。主要遇到了一个BUG,下面简单的说一下。
下面一段代码注入时机的选择,这是一个很重要的问题。
context = [_webViewvalueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//打印异常
context.exceptionHandler = ^(JSContext *context1, JSValue *exceptionValue) {
context1.exception = exceptionValue;
NSLog(@"%@", exceptionValue);
};
context[@"object"] =self; //以JSExport协议关联 native的方法
① 在webViewDidStartLoad注入
现象: 在UIWebView的webViewDidStartLoad阶段创建JSContext并暴露oc端的方法,在加载一级页面时js正常调用oc的方法,而跳转到二级页面中却无法执行oc的方法;而在webViewDidStartLoad阶段由于并未加载完js文件, 因此js层定义的函数在oc端无法执行。
原因:我跟踪了jsContext二级页面根本没有创建,这时候的jsContext还是第一次加载页面的那个对象。所以JS无法获取对象执行oc方法。
②在webVIewDidFinishLoad创建
现象:由于加载js阶段在webVIewDidFinishLoad阶段之前,因此一级页面js无法调用oc方法,但是二级页面同理也是如此
原因: 如果JS的调用OC的方法,也就是在webview加载之前那就掉不起来。因为之前JS无法获得OC对象
解决办法:
1., 可以通过在js设置setTimeout来让任务放到执行队列的末端,先执行oc层的webVIewDidFinishLoad方法,待任务完成后再执行js中的异步代码,通过这种方式可以完成js调用oc方法; 或者JS设置一个监听监听OC是否加载完成,如果完成就调用方法。
2.用一个私有API,监听何时创建好jscontext,在这时候注入。这个方法很好,只是苹果不允许上架。哎
https://github.com/TomSwift/UIWebView-TS_JavaScriptContext