2018年7月

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];

        }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容