iOS的JSContext 给JavaScript提供运行的上下文环境,可以用来监听JS的方法。
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
如果只是有单个webview 这样来监听是没问题的,但是如果webview里面有内部跳转重定向什么的,那么我们当前获取的JSContext 就不是当前监听的对象了这里我们可以直接打印context的地址来证明。
那么问题来了我们要监听onWebReload 这个js函数是否被h5调用,但此时因为重定向了所以就监听不到了
JSContext *context = [WebVie valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"onWebReload"] = ^()
{
};
为了解决这个问题和h5那边制定了一个方案首页进入到当前页面的时候让他那边 onload 事件中调用http://action:xxxxx/? 其实也就是location.href=http://action:xxxxx/?
h5端代码如下修改
<script> function iOSCallback(version) {
sessionStorage.setItem("iOSVersion", version);
}
window.onload = function() {
var zztOrigin = document.getElementsByClassName("app-element")[0].getAttribute("data-origin");
if (Origin === '2' || Origin === '3') {
try {
// android
sessionStorage.setItem("iOSVersion", window.MyWebView.getDesignatedValue("softversion", 0));
} catch(notAndroidException) {
try {
// iOS
location.href = "http://action:XXXXXX/?";
setTimeout(function() {
getDesignatedValue("softversion", 0, "iOSCallback");
}, 200);
} catch(oldVersionException) {
// old version
sessionStorage.setItem("iOSVersion", "-1");
}
}
} else {
// not zzt app
sessionStorage.setItem("iOSVersion", "-1");
}
};
</script>
而手机端通过webview的 这个代理监听来搞事情
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
当监听到了他的这个action iOS这边才来使用JSContext 然后回传值给h5
之所以能监听到就是因为是h5那边调用了window.onload 这是js加载完的方法而不需要我们手机端来监听是否加载完毕而且还延时了200毫秒,这样就能确保getDesignatedValue()我们iOS是一定能获取到的
还有iOS回传值给h5的时候调用了他们的js方法一直调用出错,后台通过safari开发模式发现iOSCallback()这个方法必须要用iOSCallback('7.7.3');不然会调用不到h5的js方法其实这个方法可以在safari的控制台里调用就可以了调用成功是手机端的问题需要排查为什么调用失败,很多时候都是语法问题导致的
最后感言 通过和h5的多次交互 如果出现些不可思议的bug让h5那边加个延时可以解决很多问题!
网友评论