oc與javaScript的交互。
基本類型轉換
通過JSValue可以把js對象轉為OC的對象
JSContext *context = [JSContext alloc] init];
JSValue *jsVal = [context evaluateScript:@“21+7”];
int oval = [jsVal to Int32];
還可以存一個JavaScript的變量在JSContext中,然后通過對于的Key來獲得。
[context evaluateScript:@"var arr = [21, 7 , 'iderzheng.com'];"];
3 JSValue *jsArr = context[@"arr"]; // Get array from JSContext
方法的轉換
各種數據類型可以轉換,Objective-C的Block也可以傳入JSContext中當做JavaScript的方法使用。
context[@“log”] = ^() {
NSLog(@“+++Begin Log+++”);
NSArray *args = [JSContext currentArguments];
for(JSValue *js in args){
NSLog(@“%@”,[js toString]);
}
JSValue *this = [JSContext currentThis];
}
[context evaluateScript:@“log(‘snow’,[7,21].{hello:’world’,js:100};)”,前面定義的block將會被調用
Block可以傳入JSContext作方法,但是JSValue沒有toBlock方法把JavaScript方法變成Block在OC中使用。
但是JSValue提供了-(JSValue *)callWithArguments:(NSArray *)arguments;發放可以反過來講參數傳進來調用方法。
還提供了-(JSValue *)invokeMethod:(NSString *)method withArgumnets:(NSArray *)arguments;讓我們可以直接簡單地調用對象上的方法。
異常處理
在JSContext中執行的JavaScript如果出現異常,只會被JSContext捕獲并存儲在exception屬性上,而不會向外拋出。時時刻刻檢查exception是否為nil顯然不合適,更合理的方式是給JSContext對象設置exceptionHander,它接受的是^(JSContext *context,JSValue *exceptionValue)形式的Block,
OC對象到JS
在OC生成的數據想要在JS中訪問,需要借助JSExport這個協議
自定義一個協議繼承自JSExport,在協議中聲明相應的屬性和方法,
@protocol CLJSObjectProtol <JSExport>
@property (nonatomic,retain) NSMutableArray *urls;
-(void)addUrlToArray:(NSString *)url;
@end
定義一個遵守了CLJSObjectProtolx協議的對象
@interface CLJSObject : NSObject<CLJSObjectProtol>
@end
@implementation CLJSObject
@synthesize urls;
-(void)addUrlToArray:(NSString *)url {
if (!self.urls) {
self.urls = [NSMutableArray array];
}
[self.urls addObject:url];
}
CLJSObject *object = [[CLJSObject alloc] init];
self.context[@"object_oc"] = _object;
在js中
<script>
var url = object_oc.urls[0]
</srcipt>
就可以訪問OC中的數據
注意:
在使用block時候,他在javaScript和OC之間的轉換建立起更多的橋梁,讓互通更方便,無論是把Block傳給JSContext對象讓其變成JavaScript方法,還是把他賦給exceptionHandler屬性,在block內都不要直接使用外部定義的JSContext對象或者JSValue,會引起循環引用。