JavaScriptCore 时代的通讯

iOS 7 开始,苹果提供了一个叫作 JavaScriptCore 的框架,使用 JavaScriptCore 框架可以实现 OC 和 JS 的互相调用,而不需要依赖「桥」来实现,怎么通讯呢?

JavaScriptCore 中 OC 调用 JS 方法

在 JS 中定义一个方法

1
2
3
function alertFunc() {
window.alert("这是一个JS中的弹框!")
}

在 webViewDidFinishLoad: 代理方法中,获取到 JSContext 对象(在这里用到的就是这个方法:

JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
 

1
2
3
4
5
6
7
8
9
- (void)webViewDidFinishLoad:(UIWebView *)webView {
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
 
[context setExceptionHandler:^(JSContext *ctx, JSValue *expectValue) {
NSLog(@"%@", expectValue);
}];
 
self.context = context;
}

在一个 button 的点击事件中可以根据 JS 定义的方法的名字获得一个 JSValue 类型对象,这个对象就是在 JS 中定义的方法,JSValue 对象通过调用 callWithArguments: 方法,执行这个 JS 方法。

1
2
3
4
5
6
7
8
- (IBAction)buttonClick:(UIButton *)sender {
if (!self.context) {
return;
}
 
JSValue *funcValue = self.context[@"alertFunc"];
[funcValue callWithArguments:nil];
}

点击按钮时,效果如下。

实现了 OC 中调用 JS 的方法。

JS 调用 OC 中的方法

在 OC 中,通过给 JSContext 的一个 key 赋值,值为一个 block,key 是 JS 中调用的方法的名字,代码如下:

在这里需要提一下,这里用到了weak-strong dance,用weak是为了防止循环引用,用weak-strong dance是为了在block内部能够访问到self的属性,所以就使用weak-strong dance。但是在xcode7.3之后就不需要使用weak-strong dance了,因为系统已经升级,不需要weak-strong dance依然能够访问到self的属性(使用weakSelf即可)。

1
2
3
4
5
6
7
8
9
10
11
12
13
self.context[@"ocAlert"] = ^{
// block 异步执行,如果涉及到 UI 的操作需要回到主线程操作
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:@"这是OC中的弹框!" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[alert dismissViewControllerAnimated:YES completion:^{
 
}];
}]];
[strongSelf.navigationController presentViewController:alert animated:YES completion:nil];
});
};

在 Web 页面中创建一个 button 并设置 button 的 onClick 事件调用 ocAlert 方法

1
<button onclick="ocAlert()">点击这里</button>

点击 Web 页面上的 button 按钮,效果如下

实现了 JS 调用 OC 中的方法。

是不是方便了很多?

写在后面

以上当然只是 JavaScriptCore 框架的一个很小的应用,使用 JavaSciptCore 框架结合 Objective-C 的动态性可以做很多事,比如著名的热修复框架 JSPatch 就是这两者的结合。这里只是演示了 JS 和 OC 之间的方法调用,并没有传输数据,JavaScriptCore 框架是很容易的实现两者之间的数据传输的。

使用 JavaScriptCore 实现通讯的 demo 放到了 GitHub,地址如下:
https://github.com/cielpy/CPYJSCoreDemo

这篇文章是整理了Kevin Guo的博客,然后把自己理解结合了一下。

最新文章

  1. touches 事件捕获不到
  2. 基于Struts2CRUD的质量属性
  3. fzu1036四塔问题(汉诺塔问题拓展)
  4. ASP.NET Web API路由规
  5. JB for iOS 9.3
  6. Provider 错误 &#39;80004005&#39; 未指定的错误 的最终解决方法
  7. CentOS常用查看系统命令
  8. Could not load db driver class: com.mysql.jdbc.Driver解决方法
  9. 将PL/SQL代码封装在机灵的包中
  10. javascript 数据结构和算法读书笔记 &gt; 第一章 javascript的编程环境和模型
  11. 正确的注销PHP SESSION
  12. BZOJ 3367: [Usaco2004 Feb]The Big Game 球赛( dp )
  13. java亦或(^)
  14. NPOI导出WPF DataGrid控件显示数据
  15. 动态代理和CGlib
  16. 一个python小白的学习之路
  17. Linux下postgresql数据库部署与配置
  18. 参考termux中包管理命令的伪装修改的arch版包管理命令
  19. camera-arm-RPI
  20. 在Raid模式下装Win10找不到固态硬盘怎么办

热门文章

  1. JAVA 写中文字符串到指定文件 中文乱码 问题解决
  2. centos下安装python2.7.9和pip以及数据科学常用的包
  3. java.sql.SQLException: Incorrect string value: &#39;\xF0\x9F\x91\x88\xE6\x88...&#39; for column &#39;content&#39; at row 1
  4. DNS安装配置
  5. java集合转换成json时问题和解决方法
  6. ControlTemplate,ItemsPanelTemplate,DataTemplate(wpf)
  7. javascript测试框架mocha
  8. Redis 存储机制
  9. 用系统工具sxstrace检查缺少的VC运行时组件
  10. IaaS中的统一存储:从设计到实现