JSCore的基本使用
一、简单介绍
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的基本使用相关推荐
- 跨平台实现基础(一)JsCore 原理和实践
前言 WebKit 是一个开源的浏览器引擎,与之相对应的引擎有Gecko(Mozilla Firefox 等使用)和Trident(也称MSHTML,IE 使用). 同时WebKit 也是苹果Mac ...
- JavaScript/Ajax/JQuery知识点(BOM/DOM/ScriptEngine/JS引擎),JSCore
捋顺JavaScript底层知识,重点讲解如原型.作用域.执行上下文.变量对象.this.闭包.按值传递.call.apply.bind.new.继承等难点概念?? JS中的继承?JS的原型模式, ...
- 移动开发中的 Web:WebView、WebKit、JSCore、Web 优化、热修复、跨平台、Native、Hybrid……...
移动开发领域近年来已经逐渐告别了野蛮生长的时期,进入了相对成熟的时代.而一直以来 Native 和 Web 的争论从未停止,通过开发者孜孜不倦的努力,Web 的效率和 Native 的体验也一直在寻求 ...
- iOS与JS交互 JSCore
源起 随着互联网移动开发的热潮,web开发近几年也出现了许多移动开发框架,比如Rect native等许多,但是还是有一定的局限性,比如需要做一个端上 H5 照片上传功能,通过 JS 去实现往往效果会 ...
- V8、JSCore、Hermes、QuickJS,hybrid开发JS引擎怎么选
- atitit..主流 浏览器 js 发动机 内核 市场份额 attialx总结vOa9
atitit..主流 浏览器 js 发动机 内核 市场份额 attialx总结vOa9 1. 浏览器内核 1 2. 浏览器的主要组件包含: 2 2.1. 主要组件体系结构 2 2.2. WebCor ...
- JSBridge 技术原理分析
- JSBridge的起源 - PhoneGap(Codova 的前身)作为 Hybrid 鼻祖框架,是一个开源的移动开发框架,允许你用标准的web技术-HTML5,CSS3和JavaS ...
- 02 小程序入门实战
技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.创建项目和目录文件结构 小程序包含一个描述整体程序的app和多个描述各自页面的page ...
- 最火移动端跨平台方案盘点:React Native、weex、Flutter
本文原文由"恋猫月亮"原创发布,原题为<移动端跨平台开发的深度解析>,本次重新整理后,为了优化阅读体验,内容略有改动,感谢原作者的无私分享. 1.前言 跨平台一直是老生 ...
最新文章
- Kubernetes基础与架构
- 英特尔在移动市场另辟蹊径
- JavaScript,JS如何控制input输入字符限制
- Curator counters
- Windows10 + Visual Studio 2017 + CMake +OpenCV编译、开发环境配置及测试
- cakephp2 框架下的 持久处理 不丢失数据库连接 后台挂起执行。
- Git workflow
- linux mmap 内存映射
- WinForm窗体自适应分辨率
- Python核心编程学习日记之模块
- 身体出现十个信号当心短命
- Redis-02-Redis数据类型与对不同类型数据的操作
- 2019-02-26-GCN资料
- 2022-2028全球全站仪市场现状及未来发展趋势
- 计算机网络及光纤通信实验教程,电子科技大学光纤通信视频教程
- 路演 - roadshow
- 浅谈UEBA基本实现步骤
- 自定义封包协议c语言,Socket分包,封包,粘包
- 计算机导论期末自测题,计算机导论期末习题da
- Codeforces 940E - Cashback
热门文章
- Linux 性能监控、测试、优化工具
- linux 版本信息 64位,Centos查看版本信息
- 【Oracle】删除手工创建的数据库
- [课后作业] 第032讲:异常处理:你不可能总是对的
- mysql安装服务和安装中常见问题install/Remove of the Service Denied与net start mysql服务启动失败解决方法
- Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1)问题解决
- spring读取多个配置properties报错“Could not resolve placeholder“的解决方案
- 树莓派VI命令大全(附vim使用异常,卸载重新安装步骤)
- 关于.NET异常处理的思考
- 对于未来chrome80 samesite问题的兼容解决方案