JavaScriptCore (一)
来源:互联网 发布:淘宝网飞机票里程 编辑:程序博客网 时间:2024/04/29 04:36
JavaScriptCore 什么是JavaScriptCore?
(一)JavaScriptCore 是一个提供网页Javascript引擎接口的的框架。框架提供了强大的功能,可以实现Swift/Objective-C 和 Javascript 代码之间的交互。(React Native 技术 就是对JavaScriptCore 强大功能的一个实际运用。)
(二)JavaScriptCore是线程安全的,它里头有几个核心组件:JSVirtualMachine,JSContext, 和JSValue
JSVirtualMachine
1. JSVirtualMachine(虚拟机制类) :JavaScript代码其实是在JSVirtualMachine类提供的环境中执行,通常不必直接对它进行操作,除非需要进行并发执行JavaScript,因为一个JSVirtualMachine是不能再同一时间执行多线程任务的,所以此时需要使用多个虚拟机制。
2. 每一个JSVirtualMachine实例都与自己的堆栈和垃圾回收机制,所以不能再不同的虚拟机制之间传递对象信息,因为虚拟机制的垃圾回收器不知道怎样处理来至其它堆栈的值。需要使用到它有两个主要情况:为了并发执行JavaScript;JavaScript 和 Objecive-C/Swift 之间桥接对象的内存管理(注意使用JSManagedValue)。
JSContext
1. JSContext是 OC支持 JavaScript执行的环境对象,是运行 JavaScript代码的环境。OC语言和 JavaScript之间的桥接,可以依赖它来实现。一个 JSContext是一个全局环境的实例,每一个JavaScript context都隶属于一个虚拟机。同虚拟机制类不同,不同context之间是可以进行对象信息传递的(一个虚拟机可以内含多个context,只要将它们放置在同一个虚拟机制下)
2. JSContext 通常与UIWebView一起使用,那应该怎样得到webview中加载的javascript代码呢,不再通过URL拦截,使用JSContext的方法直接取 UIWebView 的 context,然后进行对JS操作:context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
3. 当然也可以使(evaluateScript:)方法添加Javascript代码到context中,或者执行javascript代码。
JSValue
1. JSValue是 JavaScript值的一个引用实例对象,它可以代表任何JavaScript值类型,一个JSValue实例是搬到在它所依赖的JSContext中的,任何来至这个context中的值都会是一个JSValue类型。
(a)可实现 OC|Swift到 JavaScript中基本数据类型的转换,并能够实现原生和JavaScript之间的数据传递,
(b)可以创建JavaScript对象,通过原生的方法或者blocks提供其中的JavaScript函数实现。
2. evaluateScript: 执行javascript代码,返回值JSValue,
(三)下面直接上代码,演示一下如何使用JavaScriptCore框架来实现 Javascript 到 native的调用过程。
/// 给context中添加 javascript代码
JSContext *context = [[JSContextalloc] init];
[context evaluateScript:@"var num = 5 + 5"];
[context evaluateScript:@"var names = ['Grace', 'Ada', 'Margaret']"];
[context evaluateScript:@"var triple = function(value) { return value * 3 }"];
[context evaluateScript:@"var sendValueToNative = ({'name1':'1','value1':'a','name2':'2','value2':'b' })"];
/// 利用 context执行 javascript代码
JSValue *tripleNum = [contextevaluateScript:@"triple(num)"];
NSLog(@"Tripled: %d", [tripleNumtoInt32]);
// Tripled: 30
JSValue *value1 = [contextevaluateScript:@"sendValueToNative"];
NSLog(@"value1 = %@",[value1toDictionary]);
//value1 = {name1 = 1; name2 = 2; value1 = a; value2 = b;}
/*
对 JSContext和 JSValue实例使用下标的方式我们可以很容易地访问我们之前创建的 context的任何值。JSContext需要一个字符串下标,而 JSValue允许使用字符串或整数标来得到里面的对象和数组:
*/
JSValue *names = context[@"names"];
JSValue *initialName = names[0];
NSLog(@"The first name: %@", [initialNametoString]);
// The first name: Grace
/*
JSContext 还有另外一个有用的招数:通过设置上下文的 exceptionHandler属性,你可以观察和记录语法,类型以及运行时错误。 exceptionHandler是一个接收一个 JSContext引用和异常本身的回调处理:
*/
context.exceptionHandler = ^(JSContext *context,JSValue *exception) {
NSLog(@"JS Error: %@", exception);
};
[context evaluateScript:@"function multiply(value1, value2) { return value1 * value2 "];
// JS Error: SyntaxError: Unexpected end of script
/*
1. 现在我们知道了如何从 JavaScript环境中提取值以及如何调用其中定义的函数。那么反向呢?我们怎样才能从 JavaScript访问我们在 Objective-C或 Swift定义的对象和方法?
2. 让 JSContext访问我们的本地客户端代码的方式主要有两种:block和 JSExport协议。
3. 当一个 Objective-C block被赋给 JSContext里的一个标识符,JavaScriptCore会自动的把 block封装在 JavaScript函数里。这使得在 JavaScript中可以简单的使用 Foundation和 Cocoa类,所有的桥接都为你做好了。
4. 由于 block可以保有变量引用,而且 JSContext也强引用它所有的变量,为了避免强引用循环需要特别小心。避免保有你的 JSContext或一个 block里的任何 JSValue。相反,使用 [JSContext currentContext]得到当前上下文,并把你需要的任何值用参数传递。
*/
context[@"simplifyString"] = ^(NSString *input) {
NSMutableString *mutableString = [inputmutableCopy];
CFStringTransform((__bridgeCFMutableStringRef)mutableString,NULL, kCFStringTransformToLatin, NO);
CFStringTransform((__bridgeCFMutableStringRef)mutableString,NULL, kCFStringTransformStripCombiningMarks,NO);
return mutableString;
};
NSLog(@"%@", [contextevaluateScript:@"simplifyString('안녕하새요!')"]);
context[@"sendValue"] =
^(NSDictionary *objc)
{
return objc[@"name1"];
};
JSValue *value2 = [contextevaluateScript:@"sendValue({'name1':'one','value1':'a','name2':'2','value2':'b' })"];
NSLog(@"value2 = %@",[value2toString]);
// value2 = one
//注册一个匿名函数
JSValue *jsFunction = [contextevaluateScript:@" (function(string) { return 'hello objc '+ string })"];
//调用
JSValue *value3 = [jsFunctioncallWithArguments:@[@"coding is beauty"]];
NSLog(@"value3 = %@",[value3toString]);
//value3 = hello objc coding is beauty
// 再注册执行一个有名函数,并调用callWithArguments这个方法进行参数传值。(JS里面函数也是对象)
[context evaluateScript:@"function addfun(a,b) {return a+b}"];
JSValue *n = [context[@"addfun"]callWithArguments:@[@2, @3]];
NSLog(@"---%@", @([ntoInt32]));//---5
(四)补充。
1. Javascript 的跨平台性非常好,因此所讨论的技术其实就是如何实现Native与Javascript之间的通讯。这样做的使用示例最直接的就是实现一个WebView 和 native 的交互。JavaScriptCore就是为之而设计。
2. UIWebView 中有提供了几个代理方法,利用其中的URL拦截或者js注入等可以实现一些简单的网页到native原生的交互。
3. 罗列几篇参考文章,
//http://nshipster.cn/javascriptcore/
//https://www.raywenderlich.com/124075/javascriptcore-tutorial
//http://www.jianshu.com/p/a329cd4a67ee
- JavaScriptCore (一)
- IOS7开发~JavaScriptCore (一)
- IOS7开发~JavaScriptCore (一)
- IOS7开发~JavaScriptCore (一)
- 深入了解JavaScriptCore(一)
- javascriptcore
- JavaScriptCore
- JavaScriptCore
- JavaScriptCore
- JavaScriptCore, WebKit的JS实现(一)
- JavaScriptCore, WebKit的JS实现(一)
- JavaScriptCore, WebKit的JS实现(一)
- iOS7新JavaScriptCore框架入门介绍(一)
- iOS7新JavaScriptCore框架入门介绍(一)
- [WebKit] JavaScriptCore解析--基础篇 (一)JSC与WebCore
- [WebKit] JavaScriptCore解析--高级篇(一) SSA (static single assignment)
- [WebKit] JavaScriptCore解析--基础篇 (一)JSC与WebCore
- iOS js oc相互调用(JavaScriptCore) (一)
- VIM
- Ibox4418 开发板启动配置分析
- getApplication方法
- 无废话WCF入门教程一[什么是WCF]
- 如何在手机shell中通过命令行来启动我们的应用
- JavaScriptCore (一)
- XraGrid单元格合并
- json_decode有时解析JSON失败
- 限制TextField输入的内容
- Java 中重写(Override)与重载(Overload)详解
- NAT穿越软件
- Django和数据库打交道:数据建模
- HBase的数据导入方式
- Android Preference使用