1.javascriptcore介紹
webkit的組成部分,對js進行解析和提供執行環境。蘋果在ios7後推出的oc和javascript互相調用的開源庫。
以前ios調用oc 用stringByEvaluatingJavaScriptFromString
JS調用oc,是基於url進行攔截 代表開源庫:webviewjavascriptbridge
使用javascriptcore 能夠提高oc和js的響應速度,提高性能。
2.javascriptcore 用法
JSContext
一個JSContext 實例代表着一個js運行時環境,js代碼都需要在一個context上執行,jscontext負責管理js虛擬機中所有對象的生命週期。
JSValue 代表javascript 原始類型 函數 ,操作javavalue操作javascript ,每個javavalue強引用一個context
JSVirtualMachine
js代碼運行的虛擬機,提供javascriptcore執行需要的資源,有自己獨立的堆棧,和垃圾回收方式,線程安全,創建不同的jsvirtualmachine虛擬機對象,不同的虛擬機可以併發執行js代碼。
objects 調用 js
加載javascript代碼
context解析javascript
獲取對象和調用方法
var appendString = function(name) {
return 'string:' + name;
};
var arr = [1, 2 , 'hello world'];
//test.m
NSString *jsPath = [[NSBundle mainBundle] pathForResource:@"test"ofType:@"js"];
NSString *jsContent = [NSString stringWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:nil];
JSContext *context = [[JSContext alloc] init];
[context evaluateScript:jsContent];
JSValue *value = [context[@"appendString"] callWithArguments:@[@"hello"]];
JSValue *value1 = context[@"arr"];
NSLog(@"appendString:%@",[value toString] );//appendString:string:hello
NSLog(@"arr:%@",[value1 toArray] );
JS調用oc方法
第一個是Block
JSContext *context = [[JSContext alloc] init];
context[@"sayhi"] = ^(NSString *name) {
NSLog(@"say hi to %@",name);
};
[context evaluateScript:@"sayhi('Greg')"];
第二個是 實現JSExport協議
//定義需要暴露給js的內容,這裏我們只暴露personName和queryPersonName接口
@protocol PersonProtocol <JSExport>
@property(nonatomic,copy)NSString *personName;
-(NSString *)queryPersonName;
@end
//Person實現PersonProtocol協議,而自己定義的age和queryPersonAge接口不暴露給js
@interface Person : NSObject <PersonProtocol>
@property(nonatomic,assign)NSInteger age;
-(NSInteger)queryPersonAge;
@end
@implementation Person
@synthesize personName = _personName;
-(NSString *)queryPersonName{
return self.personName;
}
-(NSInteger)queryPersonAge{
return self.age;
}
@end
JSContext *context = [[JSContext alloc] init];
//創建Person類的對象,將他賦值給js對象
Person *person=[Person new];
person.personName = @"Greg";
person.age = 27;
context[@"person"]=person;
//可以調用獲取PersonProtocol暴露的內容
NSString *personName = [[context evaluateScript:@"person.personName"] toString]; //"Greg"
NSString *personName1 = [[context evaluateScript:@"person.queryPersonName()"] toString]; //"Greg"
//js無法調用跟age相關的內容
NSInteger age = [[context evaluateScript:@"person.age"] toInt32]; // 0
NSInteger age1 = [[context evaluateScript:@"person.queryPersonAge()"] toInt32]; /
3.封裝
將javascriptcore進行封裝,更方便ios 和 前端進行數據的交互和方法的調用,使用方式和webviewjavascriptbridge一樣,先在plist文件配置,對外暴露的oc接口需要實現指定的協議。
demo:https://github.com/HZQuan/WebViewJavaScriptCoreBridge