WKWebViewJavascriptBridge注入时机Fix

今天碰到一个问题,web那边在script完成时候注册了oc调用的handler,oc这边却调用不到,通知handler没有找到(大致这意思),调试后发现
WebViewJavascriptBridge的对象创建时间有点过晚导致,WebViewJavascriptBridge的创建时机是web加载完成,然后发起一个“wvjbscheme://BRIDGE_LOADED”链接请求,本地拦截后进行代码注入。具体可以查看 injectJavascriptFile 这个方法的执行时机。
这边的做法是采用分类覆盖方式来实现代码如下:

#import "WKWebViewJavascriptBridge+Fix.h"
#import <WebKit/WebKit.h>
#import <WebViewJavascriptBridge/WebViewJavascriptBridge_JS.h>
#import <WebViewJavascriptBridge/WKWebViewJavascriptBridge.h>

@interface WKWebViewJavascriptBridge ()
- (void) _setupInstance:(WKWebView*)webView;
@end

@implementation WKWebViewJavascriptBridge (Fix)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
+ (instancetype)bridgeForWebView:(WKWebView*)webView
{
    WKWebViewJavascriptBridge* bridge = [[self alloc] init];
    [bridge _setupInstance:webView];
    injectJavascriptFile(webView);
    [bridge reset];
    return bridge;
}
#pragma clang diagnostic pop

void injectJavascriptFile(WKWebView* webView)
{
    WKUserScript *javascriptBridge_js = [[WKUserScript alloc] initWithSource:WebViewJavascriptBridge_js() injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
    [webView.configuration.userContentController addUserScript:javascriptBridge_js];
    
    NSString* bridge_loaded_command = [NSString stringWithFormat:@"\
                                       var bridgeLoadedIframe = document.createElement('iframe');\
                                       bridgeLoadedIframe.style.display = 'none';\
                                       bridgeLoadedIframe.src = '%@://%@';\
                                       document.documentElement.appendChild(bridgeLoadedIframe);\
                                       ", kOldProtocolScheme, kBridgeLoaded];
    WKUserScript *javascriptBridge_loaded_js = [[WKUserScript alloc] initWithSource:bridge_loaded_command injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
    [webView.configuration.userContentController addUserScript:javascriptBridge_loaded_js];
}

@end

简单阐述一下:
往web注入个WebViewJavascriptBridge的创建js代码,在页面加载之前执行,这样就能保证web那边注册handler时候一定存在对象。
由于这是在加载前进行注册,所以oc这边收不到原本的“wvjbscheme://BRIDGE_LOADED”命令,在injectJavascriptFile 内的self.startupMessageQueue无法触发,新的调用也就执行不到了,所以这边补一个命令。

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

推荐阅读更多精彩内容