天天看點

iOS 基于javascriptcore封裝的 webviewjavascritpbridge

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 = [,  , '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 = ;
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