WKWebView-JS与OC交互

WKWebView-JS与OC交互,第1张

JavaScript 与 Objective-C 交互

文章目录 JavaScript 与 Objective-C 交互OC 调用 JSJS 调用 OCurl拦截scriptMessageHandler Reference

OC 调用 JS

这个比较简单,WKWebView提供了一个类似 JavaScriptCore 的方法

//执行一段js,并将结果返回,如果出错,error则不为空
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id result, NSError * _Nullable error))completionHandler;

该方法很好的解决了之前文章中提到的UIWebView使用 stringByEvaluatingJavaScriptFromString:方法的两个缺点

返回值只能是NSString

报错无法捕获

比如我想获取页面中的title,除了直接 self.webView.title 外,还可以通过这个方法:

[self.webView evaluateJavaScript:@"document.title" completionHandler:^(id _Nullable title, NSError * _Nullable error) {
        NSLog(@"调用evaluateJavaScript异步获取title:%@", title);
}];

调用js的全局函数

// iOS调用的代码
// JSMethod为js端定义的参数,parameter为给js端传递的参数
// 如果参数只有一个可以直接传递字符串,多个应该传递json
 webView?.evaluateJavaScript(“JSMethod('parameter')”, completionHandler: { (result, error) in
            debugPrint("result", result ?? "")
            debugPrint("error", error ?? ""  )
        })
// JS端的代码

可能的失败原因

iOS端调用方法应该在H5页面加载完成后(estimatedProgress == 1),不应该在viewDidLoad中就调用,否则会报无此方法JS端必须将该方法定为全局的方法,如果放在某一个对象里,可能安卓可以调用,但是iOS无法调用JS端一般会将iOS和安卓的方法分为两套,注意与JS端沟通,不是安卓可以调用iOS端就可以调用 JS 调用 OC url拦截

和UIWebView介绍到的URL拦截方法一致,都是通过自定义Scheme,在链接激活时,拦截该URL,拿到参数,调用OC方法,缺点依然明显。

scriptMessageHandler
/*! @abstract Adds a script message handler.
 @param scriptMessageHandler The message handler to add.
 @param name The name of the message handler.
 @discussion Adding a scriptMessageHandler adds a function
 window.webkit.messageHandlers..postMessage() for all
 frames.
 */
- (void)addScriptMessageHandler:(id )scriptMessageHandler name:(NSString *)name;

/*! @abstract Removes a script message handler.
 @param name The name of the message handler to remove.
 */
- (void)removeScriptMessageHandlerForName:(NSString *)name;

iOS端需要注册JS调用的该方法,在oc中添加一个scriptMessageHandler,比如:

[controller addScriptMessageHandler:self name:@"iOSMethod"]; //这里self要遵循协 WKScriptMessageHandler

则当我在js中调用下面的方法时,iOS端在 WKScriptMessageHandler 中接收js端调用改方法以及可能传递过来的参数,如果是多个参数js端要定义成为json格式,无参数至少要传递一个null,无论是否要给iOS传递参数,都必须要传递一个至少null或者空字符串等,否则iOS无法接收:

window.webkit.messageHandlers.iOSMethod.postMessage(document.cookie);
window.webkit.messageHandlers.iOSMethod.postMessage(null);
window.webkit.messageHandlers.iOSMethod.postMessage("");

我在OC中将会收到 WKScriptMessageHandler 的回调,接收协议如下:

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"iOSMethod"]) {
        NSString *cookiesStr = message.body;    //message.body返回的是一个id类型的对象,所以可以支持很多种js的参数类型(js的function除外)
        NSLog(@"当前的cookie为: %@", cookiesStr);
    }
}

在delloc里调用removeScriptMessageHandler

- (void)dealloc {
    //记得移除
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"iOSMethod"];
}

可能失败原因

JS端调用方法,但是什么都没有传递,null都没有传递 Reference

WKWebView:JavaScript与OC交互

WKWebView与JS的交互

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/993168.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存