JS方法与OC方法相互调用

2021-03-13  本文已影响0人  woshishui1243

1 利用JSContext
1 在webViewDidFinishLoad方法里,通过当前webView的键获取到jscontext



2 将context对象与js方法建立桥接联系,



通过上述两步,就可以直接js环境中直接调用OC的方法。往context中注册方法时,block也可以写成带参block

2 利用WKWebView的新特性MessageHandler来实现JS调用原生方法。
2.1 MessageHandler 是什么?
WKWebView 初始化时,有一个参数叫configuration,它是WKWebViewConfiguration类型的参数,而WKWebViewConfiguration有一个属性叫userContentController,它又是WKUserContentController类型的参数。
WKUserContentController对象有一个方法- addScriptMessageHandler:name:,
我把这个功能简称为MessageHandler。

window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
//其中<name>,就是上面方法里的第二个参数`name`。
//例如我们调用API的时候第二个参数填@"Share",那么在JS里就是:
//window.webkit.messageHandlers.Share.postMessage(<messageBody>)
//<messageBody>是一个键值对,键是body,值可以有多种类型的参数。
// 在`WKScriptMessageHandler`协议中,我们可以看到mssage是`WKScriptMessage`类型,有一个属性叫body。
// 而注释里写明了body 的类型:
Allowed types are NSNumber, NSString, NSDate, NSArray, NSDictionary, and NSNull.

2.2 怎么使用MessageHandler?
a 创建WKWebViewConfiguration对象,配置各个API对应的MessageHandler。WKUserContentController对象可以添加多个scriptMessageHandler。

- (void)viewDidLoad {
    // 这是创建configuration 的过程
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    WKPreferences *preferences = [WKPreferences new];
    preferences.javaScriptCanOpenWindowsAutomatically = YES;
    preferences.minimumFontSize = 40.0;
    configuration.preferences = preferences;
    
    WKWebView *webview = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
    [self.view addSubview:webview];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // addScriptMessageHandler 很容易导致循环引用
    // 控制器 强引用了WKWebView,WKWebView copy(强引用了)configuration, configuration copy (强引用了)userContentController
    // userContentController 强引用了 self (控制器)
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Location"];
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Share"];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    // 因此这里要记得移除handlers
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Location"];
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Share"];
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
//WKScriptMessage有两个关键属性name 和 body。因为我们给每一个OC 方法取了一个name,那么我们就可以根据name 来区分执行不同的方法。body 中存着JS 要给OC 传的参数。
    if ([message.name isEqualToString:@"Location"]) {
        //定位
    } else if ([message.name isEqualToString:@"Share"]) {
        //分享
    }
}

2.3 处理HTML中JS调用

// 传字典              
function shareClick() {
    window.webkit.messageHandlers.Share.postMessage({title:'测试分享的标题',content:'测试分享的内容',url:'http://www.baidu.com'});
}

作者:再难也要坚持
链接:https://blog.csdn.net/qq_36933797/article/details/85465024
来源:CSDN
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

上一篇 下一篇

猜你喜欢

热点阅读