h5如果引用react-history,会造成iOS 原生代理只在最开始第一次加载html时代理调用,并且html采用ajax请求,原生无法拦截到网络请求,所以造成的结果就是无论html如何跳转都无法触发iOS webview代理。
解决办法:
目前的解决办法是引入了第三方库WebViewJavascriptBridge,但是仍然非常难受,因为在断网状态下h5已经预加载内容,通过h5 react直接跳转页面,同时也并不会走webview的代理。
WebViewJavascriptBridge的集成
1.把WebViewJavascriptBridge的源码引入到工程内,如果工程内用的UIWebView 引入
#import"WebViewJavascriptBridge.h"
WKWebView 引入
#import"WKWebViewJavascriptBridge.h"
2.声明bridge属性 (踩坑,如果直接用大括号{WebViewJavascriptBridge *bridge; }这种声明方式会编译报错)
@property (nonatomic, strong) WebViewJavascriptBridge *bridge;
3.bridge初始化
self.bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView];
4.注册方法供js调用
//添加断网404页面 h5监听
- (void)registNetErrorFunction{
__weak typeof(self) weakSelf = self;
[_WKBridge registerHandler:@"showError" handler:^(id data, WVJBResponseCallback responseCallback) {
[weakSelf performSelectorOnMainThread:@selector(showErrorView) withObject:nil waitUntilDone:NO];
}];
}
5.h5需要添加js方法
functionsetupWebViewJavascriptBridge(callback) {
if(window.WebViewJavascriptBridge) { returncallback(WebViewJavascriptBridge); }
if(window.WVJBCallbacks) { returnwindow.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
varWVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
setupWebViewJavascriptBridge(function(bridge) {
//1 注册JS的方法给OC
bridge.registerHandler('JS Echo', function(data, responseCallback) {
console.log("JS Echo called with:", data)responseCallback(data)
})
})
6.GAME OVER
WKWebView源码解毒
h5一些列改动造成原生webivew代理无法触发,不仅仅如此,[webview canGoBack]方法也会一直返回是NO,但是原生safari浏览器下面的导航按钮能够监测到h5的跳转令人头疼。
最新的WKWebView还是有一些好用的方法的,比如说,webview的backForwardList属性,里面会包含跳转的页面,通过
webView.backForwardList.backList.count>0
可以判断出到底webview是否能够调用goBack 方法 ,WKWebView 执行goBack返回WKNavigation
通过定义一个全局的WKNavigation *wkNav; 然后在webview的代理中判断是否执行了goBack操作
- (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation{
if([backNavisEqual:navigation]) {
[self refreshWebView];
}
}
网友评论