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收到的回调方法
}];
}