VUE 与 原生交互(iOS为主)

2023-10-18  本文已影响0人  等不来的期待

使用WKWebView的时候,如果想要实现JS调用OC方法,除了拦截URL之外,还有一种简单的方式。那就是利用WKWebView的新特性MessageHandler来实现JS调用原生方法。

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.

MessageHandler的使用

// 这是创建configuration 的过程
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    WKPreferences *preferences = [WKPreferences new];
    preferences.javaScriptCanOpenWindowsAutomatically = YES;
    preferences.minimumFontSize = 40.0;
    configuration.preferences = preferences;
    

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // addScriptMessageHandler 很容易导致循环引用
    // 控制器 强引用了WKWebView,WKWebView copy(强引用了)configuration, configuration copy (强引用了)userContentController
    // userContentController 强引用了 self (控制器)
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"GoBack"];
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Share"];
}
//需要注意的是addScriptMessageHandler很容易引起循环引用,导致控制器无法被释放,所以需要加入以下这段:
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    // 因此这里要记得移除handlers
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Shake"];
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"GoBack"];
}

WKScriptMessageHandler的代理实现

#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
//    message.body  --  Allowed types are NSNumber, NSString, NSDate, NSArray,NSDictionary, and NSNull.
  if ([message.name isEqualToString:@"Shake"]) {
         NSLog(@"分享");
    } else if ([message.name isEqualToString:@"GoBack"]) {
         NSLog(@"返回");
    }
}

JS调iOS原生方法

const u = navigator.userAgent;
//android终端
const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
// IOS终端
const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);

 if (isiOS) {<!-- -->
  window.webkit.messageHandlers.GoBack.postMessage('');//getUserId.postMessage('')为IOS定义的原生方法
 //你的逻辑代码
 } else if (isAndroid) {<!-- -->
  window.java_obj.GoBack() //java_obj.getUserId()为安卓定义的方法,具体方法名可与其沟通
 // 你的逻辑代码
 }
上一篇 下一篇

猜你喜欢

热点阅读