一、简单介绍

JSCore全称为JavaScriptCore,是苹果公司在iOS中加入的一个新的framework。该framework为OC与JS代码相互操作的提供了极大的便利。该工程默认是没有导入工程中的,需要我们手动添加。

添加完成后,我们可以看到JavaScriptCore.h中包含以下5个主要的文件。

#import "JSContext.h"
#import "JSValue.h"
#import "JSManagedValue.h"
#import "JSVirtualMachine.h"
#import "JSExport.h"

JSContext: 代表JavaScript的执行环境。你可以创建JSContent在OC环境中执行JavaScript脚本,同时也可以在JavaScript脚本中访问OC中的值或者方法。
JSValue:是OC和JavaScript值相互转化的桥梁。他提供了很多方法把OC和JavaScript的数据类型进行相互转化。其一一对应关系如下表所示:

JSManagedValue:JSValue的包装类。JS和OC对象的内存管理辅助对象。由于JS内存管理是垃圾回收,并且JS中的对象都是强引用,而OC是引用计数。如果双方相互引用,势必会造成循环引用,而导致内存泄露。我们可以用JSManagedValue保存JSValue来避免。
JSVirtualMachine: JS运行的虚拟机。可以支持并行的JavaScript执行,管理JavaScript和OC转换中的内存管理。
JSExport:一个协议,如果JS对象想直接调用OC对象里面的方法和属性,那么这个OC对象只要实现这个JSExport协议就可以了。
下面我们通过实例案例来学习JSCore的用法。

推荐一个iOS高级交流群:624212887,群文件自行下载,不管你是小白还是大牛热烈欢迎进群 ,分享面试经验,讨论技术, 大家一起交流学习成长!希望帮助开发者少走弯路。——点击:加入

二、OC中调用JS方法

案例一:我在js中定义了一个函数add(a,b),我们需要在OC中进行调用。

-(void)OCCallJS{self.context = [[JSContext alloc] init];NSString *js = @"function add(a,b) {return a+b}";[self.context evaluateScript:js];JSValue *addJS = self.context[@"add"];JSValue *sum = [addJS callWithArguments:@[@(10),@(17)]];NSInteger intSum = [sum toInt32];NSLog(@"intSum: %zi",intSum);
}

三、JS中调用OC方法

JS中调用OC有两种方法,第一种为block调用,第二种为JSExport protocol。
案例二:我们在OC中定义了一个如下方法,我们需要在JS中对它进行调用

-(NSInteger)add:(NSInteger)a and:(NSInteger)b{return  a+b;
}

3.1、block调用

-(void)JSCallOC_block{self.context = [[JSContext alloc] init];__weak typeof(self) weakSelf = self;self.context[@"add"] = ^NSInteger(NSInteger a, NSInteger b){return [weakSelf add:a and:b];};JSValue *sum = [self.context evaluateScript:@"add(4,5)"];NSInteger intSum = [sum toInt32];NSLog(@"intSum: %zi",intSum);
}

3.2、JSExport protocol

第一步:定义一个遵守JSExport的AddJSExport协议。

@protocol AddJSExport <JSExport>
//用宏转换下,将JS函数名字指定为add;
JSExportAs(add, - (NSInteger)add:(NSInteger)a and:(NSInteger)b);
@property (nonatomic, assign) NSInteger sum;
@end

第二步:新建一个对象AddJSExportObj,去实现以上协议。

AddJSExportObj.h
@interface AddJSExportObj : NSObject<AddJSExport>
@property (nonatomic, assign) NSInteger sum;
@end
AddJSExportObj.m
@implementation AddJSExportObj
-(NSInteger)add:(NSInteger)a and:(NSInteger)b{return a+b;
}
@end

第三步:在VC中进行JS调用

-(void)JSCallOC_JSExport{self.context = [[JSContext alloc] init];//异常处理self.context.exceptionHandler = ^(JSContext *context, JSValue *exception){[JSContext currentContext].exception = exception;NSLog(@"exception:%@",exception);};self.addObj = [[AddJSExportObj alloc] init];self.context[@"OCAddObj"] = self.addObj;//js中的OCAddObj对象==>OC中的AddJSExportObj对象[self.context evaluateScript:@"OCAddObj.sum = OCAddObj.add(2,30)"];NSLog(@"%zi",self.addObj.sum);
}

四、一个从服务端下发JS脚本,执行本地方法的实现思路

案例三:本地定义了一系列方法,可以通过服务端下发js脚本去控制具体去执行那些方法。这样就可以在远端实现对于客户端的控制。
第一步:预置本地方法

-(void)initJS{__weak typeof(self) weakSelf = self;self.context[@"execute1"] = ^(){[weakSelf execute1];};self.context[@"execute2"] = ^(){[weakSelf execute2];};
}
-(void)execute1{NSLog(@"execute1");
}-(void)execute2{NSLog(@"execute2");
}

第二步:服务端下发脚本

-(NSString *)getJS{//可以从服务端下发//return @"execute1()";return @"execute2()";
}

第三步:根据服务端下发脚本执行

-(void)executeByJs{[self initJS];NSString *js = [self getJS];[self.context evaluateScript:js];
}

五、JSCore在Web容器中的使用

在UIWebView中,我们可以在- (void)webViewDidFinishLoad:(UIWebView *)webView方法中,通过KVC的方式获取到当前容器的JSContent对象,通过该对象,我们就可以方便的进行hybrid操作。

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

案例演示:在html中调研OC代码中的分享功能和调用相机功能。
第一步:HelloWord.html代码如下:

function jsCallNative(){WBBridge.callCamera();
}
function jsCallNative2(){var shareInfo = "分享内容";var str = WBBridge.share(shareInfo);alert(str);
}<input type="button" onclick="jsCallNative()" value="jsCallNative" />
<br/>
<input type="button" onclick="jsCallNative2()" value="jsCallNative2" />
<br/>

第二步:实现一个遵守JSExport的协议WebViewJSExport

@protocol WebViewJSExport <JSExport>
- (void)callCamera;
- (NSString*)share:(NSString*)shareString;
@end

第三步:当前VC需要实现WebViewJSExport

@interface ViewController ()<UIWebViewDelegate,WebViewJSExport>
@property (nonatomic, strong) JSContext *context;
@property (nonatomic, strong) UIWebView *webView;
@end
@implementation ViewController
-(void)initWebView{self.context = [[JSContext alloc] init];_webView = [[UIWebView alloc] initWithFrame:self.view.bounds];_webView.delegate = self;[self.view addSubview:_webView];NSURL *url = [[NSURL alloc] initWithString:@"http://localhost:8080/myDiary/HelloWorld.html"];NSURLRequest *request = [NSURLRequest requestWithURL:url];[self.webView loadRequest:request];
}- (void)webViewDidFinishLoad:(UIWebView *)webView{JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];_context = context;// 将本对象与 JS 中的 WBBridge 对象桥接在一起,在 JS 中 WBBridge 代表本对象[_context setObject:self forKeyedSubscript:@"WBBridge"];_context.exceptionHandler = ^(JSContext* context, JSValue* exceptionValue) {context.exception = exceptionValue;NSLog(@"异常信息:%@", exceptionValue);};
}- (void)callCamera{NSLog(@"调用相机");
}- (NSString*)share:(NSString*)shareString{NSLog(@"分享::::%@",shareString);return @"分享成功";
}
@end

这样我们就可以在webView中调用我们native组建了,实现了一个简单的hybird功能。这就补充了在UIWebView实现hybird功能的方式。还有一种方式就是iOS H5容器的一些探究(一):UIWebView和WKWebView在的比较和选择一文中见过的加载隐藏iframe,来拦截请求的方式。

补充
对于WKWebView,目前还没有能够拿到JSContent的对象的方式。

六、参考资料

javascriptcore官方资料

JavaScriptCore 使用

iOS7新JavaScriptCore框架入门介绍

七、联系方式

推荐一个iOS高级交流群:624212887,群文件自行下载,不管你是小白还是大牛热烈欢迎进群 ,分享面试经验,讨论技术, 大家一起交流学习成长!希望帮助开发者少走弯路。——点击:加入

如果觉得对你还有些用,就关注小编+喜欢这一篇文章。你的支持是我继续的动力。

下篇文章预告:Weex开发之路(一):开发环境搭建

文章来源于网络,如有侵权,请联系小编删除。

转载于:https://juejin.im/post/5c14ab776fb9a049f9127737

JSCore的基本使用相关推荐

  1. 跨平台实现基础(一)JsCore 原理和实践

    前言 WebKit 是一个开源的浏览器引擎,与之相对应的引擎有Gecko(Mozilla Firefox 等使用)和Trident(也称MSHTML,IE 使用). 同时WebKit 也是苹果Mac ...

  2. JavaScript/Ajax/JQuery知识点(BOM/DOM/ScriptEngine/JS引擎),JSCore

    捋顺JavaScript底层知识,重点讲解如原型.作用域.执行上下文.变量对象.this.闭包.按值传递.call.apply.bind.new.继承等难点概念??   JS中的继承?JS的原型模式, ...

  3. 移动开发中的 Web:WebView、WebKit、JSCore、Web 优化、热修复、跨平台、Native、Hybrid……...

    移动开发领域近年来已经逐渐告别了野蛮生长的时期,进入了相对成熟的时代.而一直以来 Native 和 Web 的争论从未停止,通过开发者孜孜不倦的努力,Web 的效率和 Native 的体验也一直在寻求 ...

  4. iOS与JS交互 JSCore

    源起 随着互联网移动开发的热潮,web开发近几年也出现了许多移动开发框架,比如Rect native等许多,但是还是有一定的局限性,比如需要做一个端上 H5 照片上传功能,通过 JS 去实现往往效果会 ...

  5. V8、JSCore、Hermes、QuickJS,hybrid开发JS引擎怎么选

  6. atitit..主流 浏览器 js 发动机 内核 市场份额 attialx总结vOa9

    atitit..主流 浏览器 js 发动机  内核 市场份额 attialx总结vOa9 1. 浏览器内核 1 2. 浏览器的主要组件包含: 2 2.1. 主要组件体系结构 2 2.2. WebCor ...

  7. JSBridge 技术原理分析

    -     JSBridge的起源    - PhoneGap(Codova 的前身)作为 Hybrid 鼻祖框架,是一个开源的移动开发框架,允许你用标准的web技术-HTML5,CSS3和JavaS ...

  8. 02 小程序入门实战

    技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.创建项目和目录文件结构 小程序包含一个描述整体程序的app和多个描述各自页面的page ...

  9. 最火移动端跨平台方案盘点:React Native、weex、Flutter

    本文原文由"恋猫月亮"原创发布,原题为<移动端跨平台开发的深度解析>,本次重新整理后,为了优化阅读体验,内容略有改动,感谢原作者的无私分享. 1.前言 跨平台一直是老生 ...

最新文章

  1. Kubernetes基础与架构
  2. 英特尔在移动市场另辟蹊径
  3. JavaScript,JS如何控制input输入字符限制
  4. Curator counters
  5. Windows10 + Visual Studio 2017 + CMake +OpenCV编译、开发环境配置及测试
  6. cakephp2 框架下的 持久处理 不丢失数据库连接 后台挂起执行。
  7. Git workflow
  8. linux mmap 内存映射
  9. WinForm窗体自适应分辨率
  10. Python核心编程学习日记之模块
  11. 身体出现十个信号当心短命
  12. Redis-02-Redis数据类型与对不同类型数据的操作
  13. 2019-02-26-GCN资料
  14. 2022-2028全球全站仪市场现状及未来发展趋势
  15. 计算机网络及光纤通信实验教程,电子科技大学光纤通信视频教程
  16. 路演 - roadshow
  17. 浅谈UEBA基本实现步骤
  18. 自定义封包协议c语言,Socket分包,封包,粘包
  19. 计算机导论期末自测题,计算机导论期末习题da
  20. Codeforces 940E - Cashback

热门文章

  1. Linux 性能监控、测试、优化工具
  2. linux 版本信息 64位,Centos查看版本信息
  3. 【Oracle】删除手工创建的数据库
  4. [课后作业] 第032讲:异常处理:你不可能总是对的
  5. mysql安装服务和安装中常见问题install/Remove of the Service Denied与net start mysql服务启动失败解决方法
  6. Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1)问题解决
  7. spring读取多个配置properties报错“Could not resolve placeholder“的解决方案
  8. 树莓派VI命令大全(附vim使用异常,卸载重新安装步骤)
  9. 关于.NET异常处理的思考
  10. 对于未来chrome80 samesite问题的兼容解决方案