WKWebview 和 js 相互调用及传值

2020-06-23  本文已影响0人  两个小棉袄

webview 用的是WKWebView,需实现协议<WKScriptMessageHandler,WKNavigationDelegate,WKUIDelegate>

// js调用oc
// 原理
//1、JS与iOS约定好JStoOC方法,用作JS在调用iOS时的方法;
//2、iOS使用WKUserContentController的-addScriptMessageHandler:name:方法监听name为JStoOC的消息;
//3、iOS在-userContentController:didReceiveScriptMessage:方法中读取name为JStoOC的消息数据message.body。

关键代码如下

// 初始化
- (instancetype)init
{
    self = [super init];
    if (self) {
        WKWebViewConfiguration *config = [WKWebViewConfiguration new];
        //初始化偏好设置属性:preferences
        config.preferences = [WKPreferences new];
        //是否支持JavaScript, 默认是yes ,也可以不设置
        config.preferences.javaScriptEnabled = YES;
        
        config.userContentController = [WKUserContentController new];
        // 注入方法名是 "JStoOC",可以在WKScriptMessageHandler代理中接收到js的调用
        [config.userContentController addScriptMessageHandler:self name:@"JStoOC"];
        
        // frame 可以根据实际情况设置
        _webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, 0,0) configuration:config];
        _webView.UIDelegate = self;
        _webView.navigationDelegate = self;
    }
    return self;
}

- (void)dealloc
{
    // 注册了方法,一定要remove,防止循环引用
    [[self.webView configuration].userContentController removeScriptMessageHandlerForName:@"JStoOC"];
}

//WKScriptMessageHandler 协议的回调方法
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
     if ([message.name isEqualToString:@"JStoOC"]) {
        // js 传的参数在 message.body 里
        // 执行业务逻辑
        // ...
    }
}

// oc调用js
// 原理
//1、iOS与JS约定好OCtoJS方法,用作iOS在调用JS时的入口方法;
//2、iOS在页面加载完成 或者 js主动调用oc注入方法需回传参数场景
//3、iOS使用WKWebView的-evaluateJavaScript:completionHandler:方法执行拼接好的JS代码;
//4、iOS通过completionHandler收到JS给OCtoJS方法的回调。

// WKNavigationDelegate 协议的 回调方法,页面加载完,调用js 方法
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
   
     // 无参数场景
     [webView evaluateJavaScript:@"OCtoJS()" completionHandler:^(id data, NSError * _Nullable error) {
        // 调用js后, OC收到的回调方法
    }];
}

补充一点,这个是有参数的情况

// 这个地方需要注意,
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    
    // 方法名字及参数结构
//    OCtoJS({
//        "businessFunctionName" : "tokenData(业务方法名字)",
//        "param" : {
//            "key1" : "value1",
//            "key2" : "value2",
//        }
//    })
//
    NSDictionary *paramDic = @{@"businessFunctionName":@"tokenData",@"param":@{@"key1":@"value1",@"key2":@"value2"}};
    //转为json
    NSData *data = [NSJSONSerialization dataWithJSONObject:paramDic options:(NSJSONWritingPrettyPrinted) error:nil];
    NSString *paramStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSString *jsonStr = [NSString stringWithFormat:@"OCtoJS(%@)",paramStr];
    [webView evaluateJavaScript:jsonStr completionHandler:^(id data, NSError * _Nullable error) {
        // 调用js后, OC收到的回调方法
    }];
}

上一篇下一篇

猜你喜欢

热点阅读