WebViewJavascriptBridge 注册逻辑

一、bridge 初始化

self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView];

这里并没有注册 js 的 bridge。而是在 js 第一次调用 native 的时候,才去执行的 bridge 中的 js 方法。去注册 js 端的 bridge。

二、native 注册 methods

native 调用 registerHandler 方法,并没有真的注入方法到 js context 里面,而是存储到了_base.messageHandlers 这个Dictionary 中。

[self.bridge registerHandler:@"ObjC Echo" handler:^(id data, WVJBResponseCallback responseCallback) {
    NSLog(@"ObjC Echo called with: %@", data);
    responseCallback(data);
}];
- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler {
    _base.messageHandlers[handlerName] = [handler copy];
}

三、注册 js 端的 bridge

function setupWebViewJavascriptBridge(callback) {
    if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
    if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
    window.WVJBCallbacks = [callback];
    var WVJBIframe = document.createElement('iframe');
    WVJBIframe.style.display = 'none';
    WVJBIframe.src = 'https://__bridge_loaded__';
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}

在第一个 js 调用 native 方法的时候,window.WebViewJavascriptBridge 是没有值的,所以下面会调用一个 https://__bridge_loaded__ 的链接,native 端 bridge 接收到这个链接后,才去执行 注入的 js 端 bridge。

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    if (webView != _webView) { return; }
    NSURL *url = navigationAction.request.URL;
    __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;

    if ([_base isWebViewJavascriptBridgeURL:url]) {
        if ([_base isBridgeLoadedURL:url]) {// 判断是 load bridge的 url
            [_base injectJavascriptFile];
        } else if ([_base isQueueMessageURL:url]) {// 判断是 执行方法
            [self WKFlushMessageQueue];
        } else {
            [_base logUnkownMessage:url];
        }
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }
    
    if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
        [_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
    } else {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}

你可能感兴趣的:(WebViewJavascriptBridge 注册逻辑)