美文网首页
15.OC 与 vue 以及 原生html 相互调用方法

15.OC 与 vue 以及 原生html 相互调用方法

作者: 枫之叶_小乙哥 | 来源:发表于2020-04-30 16:54 被阅读0次

1.js调用oc的方法(vue && 原生html)

(1.1)创建webview的时候注册js要用到的方法
- (WKWebView *)webview{
    if (!_webview) {
        WKUserContentController *wkUController = [[WKUserContentController alloc] init];
        // 注册js要调用的方法(requireIOSToken)
        [wkUController addScriptMessageHandler:self  name:@"requireIOSToken"];
        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
        config.userContentController = wkUController;
        _webview = [[WKWebView alloc] initWithFrame:CGRectMake(0, kNavBarHeight, kScreenWidth, kScreenHeight - kNavBarHeight) configuration:config];
        //        _webview = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:webConfig];
        _webview.allowsBackForwardNavigationGestures = YES;
        _webview.UIDelegate = self;
        _webview.navigationDelegate = self;
        _webview.scrollView.delegate = self;
        // 禁止网页边缘反弹
        //        _webview.scrollView.bounces = NO;
        _webview.scrollView.mj_header = self.refreshHeader;
        if (@available(iOS 11.0, *)) {
            _webview.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        } else {
            self.automaticallyAdjustsScrollViewInsets = false;
        }
    }
    return _webview;
}
(1.2)遵守WKScriptMessageHandler协议
@interface WebViewController ()<WKScriptMessageHandler>
(1.3)实现WKScriptMessageHandler代理方法
#pragma mark - WKScriptMessageHandler   ----  监听js调用oc的方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    
    if([message.name isEqualToString:@"requireIOSToken"]){
        NSDictionary *userDict = @{@"token": @"666666666666"};
        // 这里option要使用kNilOptions, 使用NSJSONWritingPrettyPrinted, 前端会识别不了字典对象
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:userDict
                                                           options:kNilOptions
                                                             error:nil];
        NSString * jsonDict = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        // 调用前端的receiveIOSToken方法, 并传递对象:{token : '666666666666'}作为方法参数
        NSString *jsString = [NSString stringWithFormat:@"receiveIOSToken('%@')", jsonDict];
        // oc调用js的receiveIOSToken方法
        [self.webview evaluateJavaScript:jsString completionHandler:^(id _Nullable result, NSError * _Nullable error) {
            NSLog(@"result: %@  ----- error: %@", result, error);
        }];
    }
}
(1.4)普通html发送请求token的方法, 和被oc调用的方法
<!DOCTYPE html>

<head>
    <title>JS交互OC</title>
        <meta charset="utf-8">
    </head>
<body>
    
    <h2 style="text-align:center">js get token</h2>
    
    
    <p style="text-align:center">
    
    <button id="btn2" type = "button" onclick = "requireIOSToken()"> JS调用OC:带参数  </button>
    </p>
    
    <script type = "text/javascript">
    
    // js向oc发送获取token的请求
    function requireIOSToken(){
        // 可以不传参数
        window.webkit.messageHandlers.requireIOSToken.postMessage({"params":"我是参数"});
        // window.webkit.messageHandlers.requireIOSToken.postMessage({});
    }
    
    // js收到oc发送过来的token
    function receiveIOSToken(tokenStr){    // objStr 对象格式  {"token":"666666666666"}
        
       alert("oc 传递的对象为: " + tokenStr);
    }
    
    </script>
    
</body>

</html>
(1.5)上述方法放在vue会报找不到receiveIOSToken的错误. 原因是,使用vue的话,需要将oc要调用的方法预先挂载到window的created生命周期去
  // 在vue中,只需要将方法绑定到window中即可,ios就能够调用到

created(){
    //供iso调用前需要绑定到window上
    window.receiveIOSToken = this.receiveIOSToken;
}

mounted(){
        // js收到oc发送过来的token
    function receiveIOSToken(tokenStr){    // objStr 对象格式  {"token":"666666666666"}
        
       alert("oc 传递的对象为: " + tokenStr);
    }
}

2.vue或者html调用oc的方法

// 注:requireIOSToken是ios的方法,params为传递给ios的参数,messageHandlers在电脑浏览器上可能会报错,但是在ios的webkit里面正常,所以这里书写的时候要注意这个方法尽量写在最后,不然后面的代码不能执行,或使用try...catch
window.webkit.messageHandlers.requireIOSToken.postMessage({params :'我是参数'});

3.补充说明, 如果要将字典转成json传递给前端时, 转换的options要使用kNilOptions, 不要使用默认的NSJSONWritingPrettyPrinted, 否则,会报如下的错误:

Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred" UserInfo={NSLocalizedDescription=A JavaScript exception occurred

原因是用NSJSONWritingPrettyPrinted输出的结果是

{
  "token" : "666666666666"
}

用kNilOptions输出的结果才是json:

{"token":"666666666666"}

NSJSONWritingPrettyPrinted格式转换的json,前端是无法识别的

相关文章

网友评论

      本文标题:15.OC 与 vue 以及 原生html 相互调用方法

      本文链接:https://www.haomeiwen.com/subject/lmttghtx.html