WKWebview与JS交互的问题

    首先向大家推荐一篇文章关于iOS与js交互知识点的总结,个人认为有助于大家记忆和理解,感谢作者的整理。

https://github.com/Haley-Wong/JS_OC

    关于OC与JS交互方法,我主要使用的是WKWebview,所以js调用oc方法并传值,oc调用js方法并传值,我使用的是MessageHandler。JS_OC_MessageHandler是利用WKWebView提供的新的API实现的JS调用原生OC,更简洁和方便。

一、js调用oc方法:

首先在viewdidload里,配置WKUserContentController和配置WKWebView,代码如下:

//js调用iOS方法配置
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    configuration.userContentController = userContentController;
    configuration.preferences=[[WKPreferences alloc]init];
    configuration.preferences.javaScriptEnabled=YES;
    configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
    
    //wkwebview配置
    wkwebview =[[WKWebView alloc]initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height-20) configuration:configuration];
    wkwebview.scrollView.bounces=NO;
    wkwebview.navigationDelegate=self;
    wkwebview.UIDelegate = self;
    wkwebview.backgroundColor = [UIColor clearColor];
    wkwebview.opaque = NO;
    wkwebview.scrollView.scrollEnabled=NO;
    [self.view addSubview:wkwebview];

其次,在viewWillAppear里添加ScriptMessageHandler,在viewWillDisappear移除ScriptMessageHandler,代码如下:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [wkwebview.configuration.userContentController addScriptMessageHandler:self name:@"backToIOS"];//h5模块首页返回到导航的返回按钮
    [wkwebview.configuration.userContentController addScriptMessageHandler:self name:@"addCollect"];//添加到收藏夹
    [wkwebview.configuration.userContentController addScriptMessageHandler:self name:@"cancelCollect"];//取消收藏
}
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    [wkwebview.configuration.userContentController removeScriptMessageHandlerForName:@"backToIOS"];//h5模块首页返回到导航的返回按钮
    [wkwebview.configuration.userContentController removeScriptMessageHandlerForName:@"addCollect"];//添加到收藏夹
    [wkwebview.configuration.userContentController removeScriptMessageHandlerForName:@"cancelCollect"];//取消收藏
}

最后,在代理方法里:

#pragma mark - WKScriptMessageHandler h5交互(js调iOS方法)
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    
    NSLog(@"方法名:%@", message.name);
    NSLog(@"参数:%@", message.body);
    
    if ([message.name isEqualToString:@"backToIOS"]) {
        //h5模块首页返回到导航的返回按钮
        [self backToLast];
    }
    if ([message.name isEqualToString:@"addCollect"]) {
        //添加到收藏夹
        [self requestForAddCollect];//调用添加收藏接口
  
    }
    if ([message.name isEqualToString:@"cancelCollect"]) {
        //取消收藏
        [self requestForCancelCollect];//调用取消收藏接口
    }
    
    
}

二、oc给js传值:

[wkwebview evaluateJavaScript:@"collectResult('收藏成功')" completionHandler:nil];

三、html相关代码:

js调用oc方法:其中包含两个方法,返回和收藏,一个传type一个不传。

function goBack(){
    try{window.webkit.messageHandlers.backToIOS.postMessage(null);}catch (e){}
}
function  _addFavorite(){
    var html = document.getElementById('favorite').innerHTML;
    if(html == '加入收藏'){
        try{window.webkit.messageHandlers.addCollect.postMessage({type:'1'});}catch (e){}
    }else{
        try{window.webkit.messageHandlers.cancelCollect.postMessage({type:'0'}); }catch (e){}
    }
}

oc调用js方法,给js传值:

扫描二维码关注公众号,回复: 4945678 查看本文章
<script>
    var VM = new Vue({
        el: '#app',
        data: function () {
            return {
                favorite:'加入收藏'
          };
        },
                     mounted() {
                     window.collectResult = this.collectResult
                     },
        methods: {
          collectResult:function(res) {
             this.$toast({
                        message: res,
                        position: 'middle',
                        duration: 5000
             });
             if(res.indexOf("收藏成功")>-1){
                this.favorite ='取消收藏';
             }else{
               this.favorite ='加入收藏';
                     
             }
          }, 
      }
    })
    </script>

四、关于oc给js传值,遇到的大坑:

当我调用collectResult方法,给其传一个字符串时,遇到传值方法报error:

Error Domain=WKErrorDomain Code=4 "发生 JavaScript 异常" UserInfo={WKJavaScriptExceptionLineNumber=1, WKJavaScriptExceptionMessage=ReferenceError: Can't find variable: collectResult

然后js那边也没有收到我的值,我这边打印result是null。

原因是由于h5同事是用vue2.0写的,vue中需要将方法挂载到全局中,正确的前端写法是在mounted方法里面加上window.collectResult = this.collectResult。

即在代码里加上:

mounted() {
    window.payResult = this.payResult
},

猜你喜欢

转载自blog.csdn.net/ZhongLv_HoneyMoon/article/details/86507401