iOS-OC与js交互:MessageHandler(userContentController代理方法不执行解决)

iOS与JS交互的方法主要有四种如下:

1、拦截url(适用于UIWebView和WKWebView)
2、JavaScriptCore(只适用于UIWebView,iOS7+)
3、WKScriptMessageHandler(只适用于WKWebView,iOS8+)
4、WebViewJavascriptBridge(适用于UIWebView和WKWebView,属于第三方框架)

本便主要讲解WKWebView的MessageHandler方式实现交互;因为相比与 UIWebView, WKWebView 存在很多优势,主要是在性能、稳定性方面有很大提升占用内存更少 协议方法及功能都更细致

WKWebView 初始化时,有一个参数叫configuration,它是WKWebViewConfiguration类型的参数,而WKWebViewConfiguration有一个属性叫userContentController,它又是WKUserContentController类型的参数。WKUserContentController对象有一个方法

- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;

我把这个功能简称为MessageHandler。

1、JS调用OC时,这句代码非常重要

[config.userContentController addScriptMessageHandler:self name:@"callFunciton"];

在创建wkWebView时,需要将被js调用的方法注册进去,oc与js端对应实现

- (void)setWKWebview{
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    config.preferences = [[WKPreferences alloc] init];
    config.preferences.minimumFontSize = 10;
    config.preferences.javaScriptEnabled = YES;
    config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
    config.userContentController = [[WKUserContentController alloc] init];
    config.processPool = [[WKProcessPool alloc] init];
    config.userContentController = [WKUserContentController new];
    //在创建wkWebView时,需要将被js调用的方法注册进去,oc与js端对应实现
    [config.userContentController addScriptMessageHandler:self name:@"callFunciton"];
    
    WKWebView *wkWebView = [[WKWebView alloc]initWithFrame:self.view.frame configuration:config];
    self.wkWebView = wkWebView;
    wkWebView.navigationDelegate = self;
    wkWebView.UIDelegate = self;
    NSURLRequest *request = [[NSURLRequest alloc]initWithURL:self.url];
    [wkWebView loadRequest:request];
    [self.view addSubview:wkWebView];
}

- addScriptMessageHandler:name:有两个参数,第一个参数是userContentController的代理对象,第二个参数是JS里发送postMessage的对象。 
所以要使用MessageHandler功能,就必须要实现WKScriptMessageHandler协议。 
2、JS中使用方法:

window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
//其中<name>,就是上面方法里的第二个参数`name`。
//例如我们调用API的时候第二个参数填@"callFunction",那么在JS里就是:
window.webkit.messageHandlers.callFunction.postMessage(<messageBody>)
//<messageBody>是一个键值对,键是body,值可以有多种类型的参数,body 的类型:Allowed types are NSNumber, NSString, NSDate, NSArray, NSDictionary, and NSNull

重要的事情说三遍!重要的事情说三遍!重要的事情说三遍!

window.webkit.messageHandlers.AppModel.postMessage(NULL或者其他参数),参数messageBody里面不能为空什么都不写,不然不会走代理方法

3、实现WKScriptMessageHandler代理方法,当js调用callFunction方法时,会回调此代理方法:

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ 
    if ([message.name isEqualToString:@"callFunction"]) { 
        //调用原生扫码 
    } 
}

4、addScriptMessageHandler很容易引起循环引用,导致控制器无法被释放

- (void)dealloc{
    [self.wkWebView.configuration.userContentController removeScriptMessageHandlerForName:@"callFunction"];
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值