一、简介
Hybrid Development混合开发是目前移动端开发异常火热的新兴技术,它能够实现跨平台开发,极大地节约了人力和资源成本。跨平台开发催生了很多新的开源框架,就目前而言,在混合开发中比较流行的有FaceBook开源React Native,有Goggle开源的Flutter。React Native实现的是通过下发JS脚本的方式达到JS与Native交互。Flutter实现的则是通过采用现代响应式框架来构建UI,Flutter与ReactiveCocoa框架配合使用最佳。当然开发者也可以在Native中内嵌WebView的方式(WebKit)实现混合开发。虽然方式不同,但目的相同,都是跨平台,殊途同归吧。对跨平台有了粗略的了解后,再来看看iOS系统中对JS与Native是如何交互的,其实,系统是给开发者提供了一个极其强大的框架来实现这个功能的,即JavaScriptCore框架。这个框架通过定义JSValue值对象和声明JSExport协议作为桥梁完成Native与JS的通信。JS虽然是单线程语言,但是iOS是支持多线程执行任务的,开发者可以在异步情况下执行任意一个环境的JavaScript代码。大概结构图如下:
二、分析
参考这上图,可以看出JavaScriptCore框架结构还是很清晰的,JavaScriptCore中有那么几个核心的类在开发者是很常用的,需要弄懂它们代表的意思。
三、API
知道了这几个核心类的概念已经对这个框架有了个基本的认识,具体的API如何使用,我们可以选择性点击去深入研究一下。只有对它们的属性和方法都了如指掌,开发起来才能得心应手,手到擒来。哎呀妈,不废话了。。。例如JSContext和JSValue开发中必用的类,额外的可能还会用JSManagerValue,如下:
JSContetxt类:
//初始化,可以选择对应的虚拟机
- (instancetype)init;
- (instancetype)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine;
//执行js代码,返回js值对象
- (JSValue *)evaluateScript:(NSString *)script;
- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL;
//获取当前的js上下文
+ (JSContext *)currentContext;
//获取当前的js执行函数,返回js值对象
+ (JSValue *)currentCallee;
//获取当前的js函数中this指向的对象,返回js值对象
+ (JSValue *)currentThis;
//获取当前的js函数中的所有参数
+ (NSArray *)currentArguments;
//js的全局对象
@property (readonly, strong) JSValue *globalObject;
//js执行的异常数据
@property (strong) JSValue *exception;
@property (copy) void(^exceptionHandler)(JSContext *context, JSValue *exception);
//js运行的虚拟机
@property (readonly, strong) JSVirtualMachine *virtualMachine;
//js上下文名称
@property (copy) NSString *name;
//分类
@interface JSContext (SubscriptSupport)
//获取和设置属性为js全局对象
- (JSValue *)objectForKeyedSubscript:(id)key;
- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key;
@end
//分类(C函数风格)
@interface JSContext (JSContextRefSupport)
//获取和设置全局上下文
+ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)jsGlobalContextRef;
@property (readonly) JSGlobalContextRef JSGlobalContextRef;
@end
JSValue类:
//js上下文
@property (readonly, strong) JSContext *context;
//使用OC数据初始化js值对象,创建有值的JSValue
+ (JSValue *)valueWithObject:(id)value inContext:(JSContext *)context;
+ (JSValue *)valueWithBool:(BOOL)value inContext:(JSContext *)context;
+ (JSValue *)valueWithDouble:(double)value inContext:(JSContext *)context;
+ (JSValue *)valueWithInt32:(int32_t)value inContext:(JSContext *)context;
+ (JSValue *)valueWithUInt32:(uint32_t)value inContext:(JSContext *)context;
+ (JSValue *)valueWithPoint:(CGPoint)point inContext:(JSContext *)context;
+ (JSValue *)valueWithRange:(NSRange)range inContext:(JSContext *)context;
+ (JSValue *)valueWithRect:(CGRect)rect inContext:(JSContext *)context;
+ (JSValue *)valueWithSize:(CGSize)size inContext:(JSContext *)context;
//使用OC数据初始化js值对象,创建空的JSValue
+ (JSValue *)valueWithNewObjectInContext:(JSContext *)context;
+ (JSValue *)valueWithNewArrayInContext:(JSContext *)context;
+ (JSValue *)valueWithNewRegularExpressionFromPattern:(NSString *)pattern flags:(NSString *)flags inContext:(JSContext *)context;
+ (JSValue *)valueWithNewErrorFromMessage:(NSString *)message inContext:(JSContext *)context;
+ (JSValue *)valueWithNewPromiseInContext:(JSContext *)context fromExecutor:(void (^)(JSValue *resolve, JSValue *reject))callback;
+ (JSValue *)valueWithNewPromiseResolvedWithResult:(id)result inContext:(JSContext *)context;
+ (JSValue *)valueWithNewPromiseRejectedWithReason:(id