iOS與JS互動實戰篇(ObjC版)

來源:互聯網
上載者:User

標籤:

前言ObjectiveC與Js互動是常見的需求,可對於新手或者所謂的高手而言,其實並不是那麼簡單明了。這裡只介紹iOS7.0後出來的JavaScriptCore framework。關於JavaScriptCore本教程中所涉及到的幾種類型: JSContext, JSContext是代表JS的執行環境,通過-evaluateScript:方法就可以執行一JS代碼 JSValue, JSValue封裝了JS與ObjC中的對應的類型,以及調用JS的API等 JSExport, JSExport是一個協議,遵守此協議,就可以定義我們自己的協議,在協議中聲明的API都會在JS中暴露出來,才能調用ObjC與JS互動方式通過JSContext,我們有兩種調用JS代碼的方法: 1、直接調用JS代碼 2、在ObjC中通過JSContext注入模型,然後調用模型的方法直接調用JS代碼 // 一個JSContext對象,就類似於Js中的window, // 只需要建立一次即可。 self.jsContext = [[JSContext alloc] init]; // jscontext可以直接執行JS代碼。 [self.jsContext evaluateScript:@"var num = 10"]; [self.jsContext evaluateScript:@"var squareFunc = function(value) { return value * 2 }"]; // 計算正方形的面積 JSValue *square = [self.jsContext evaluateScript:@"squareFunc(num)"]; // 也可以通過下標的方式擷取到方法 JSValue *squareFunc = self.jsContext[@"squareFunc"]; JSValue *value = [squareFunc callWithArguments:@[@"20"]]; NSLog(@"%@", square.toNumber); NSLog(@"%@", value.toNumber);這種方式是沒有注入模型到JS中的。這種方式使用起來不太合適,通常在JS中有很多全域的函數,為了防止名字重名,使用模型的方式是最好不過了。通過我們協商好的模型名稱,在JS中直接通過模型來調用我們在ObjC中所定義的模型所公開的API。通過注入模型的方式互動首先,我們需要先定義一個協議,而且這個協議必須要遵守JSExport協議。@protocol JavaScriptObjectiveCDelegate // JS調用此方法來調用OC的系統相簿方法- (void)callSystemCamera;// 在JS中調用時,函數名應該為showAlertMsg(arg1, arg2)// 這裡是只兩個參數的。- (void)showAlert:(NSString *)title msg:(NSString *)msg;// 通過JSON傳過來- (void)callWithDict:(NSDictionary *)params;// JS調用Oc,然後在OC中通過調用JS方法來傳值給JS。- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params;@end接下來,我們還需要定義一個模型:// 此模型用於注入JS的模型,這樣就可以通過模型來調用方法。@interface HYBJsObjCModel : NSObject @property (nonatomic, weak) JSContext *jsContext;@property (nonatomic, weak) UIWebView *webView;@end實現這個模型:@implementation HYBJsObjCModel- (void)callWithDict:(NSDictionary *)params { NSLog(@"Js調用了OC的方法,參數為:%@", params);}// Js調用了callSystemCamera- (void)callSystemCamera { NSLog(@"JS調用了OC的方法,調起系統相簿"); // JS調用後OC後,又通過OC調用JS,但是這個是沒有傳參數的 JSValue *jsFunc = self.jsContext[@"jsFunc"]; [jsFunc callWithArguments:nil];}- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params { NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params); // 調用JS的方法 JSValue *jsParamFunc = self.jsContext[@"jsParamFunc"]; [jsParamFunc callWithArguments:@[@{@"age": @10, @"name": @"lili", @"height": @158}]];}- (void)showAlert:(NSString *)title msg:(NSString *)msg { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertView *a = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [a show]; });}@end接下來,我們在controller中在webview載入完成的代理中,給JS注入模型。#pragma mark - UIWebViewDelegate- (void)webViewDidFinishLoad:(UIWebView *)webView { self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; // 通過模型調用方法,這種方式更好些。 HYBJsObjCModel *model = [[HYBJsObjCModel alloc] init]; self.jsContext[@"OCModel"] = model; model.jsContext = self.jsContext; model.webView = self.webView; self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; NSLog(@"異常資訊:%@", exceptionValue); };}我們是通過webView的valueForKeyPath擷取的,其路徑為documentView.webView.mainFrame.javaScriptContext。這樣就可以擷取到JS的context,然後為這個context注入我們的模型對象。我們先寫兩個JS方法: var jsFunc = function() { alert(‘Objective-C call js to show alert‘); } var jsParamFunc = function(argument) { document.getElementById(‘jsParamFuncSpan‘).innerHTML = argument[‘name‘]; }這裡我們定義了兩個JS方法,一個是jsFunc,不帶參數。另一個是jsParamFunc,帶一個參數。接下來,我們在html中的body中添加以下代碼:Test how to use objective-c call js現在就可以測試代碼了。當我們點擊第一個按鈕:Call ObjC system camera時,通過OCModel.callSystemCamera(),就可以在HTML中通過JS調用OC的方法。在OC代碼中,我們的callSystemCamera方法體中,添加了以下兩行代碼,就是擷取HTML中所定義的JS就去jsFunc,然後調用它。 JSValue *jsFunc = self.jsContext[@"jsFunc"]; [jsFunc callWithArguments:nil];這樣就可以在JS調用OC方法時,也讓OC反饋給JS。看看下面傳字典參數:- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params { NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params); // 調用JS的方法 JSValue *jsParamFunc = self.jsContext[@"jsParamFunc"]; [jsParamFunc callWithArguments:@[@{@"age": @10, @"name": @"lili", @"height": @158}]];}擷取我們在HTML中定義的jsParamFunc方法,然後調用它並傳了一個字典作為參數。

iOS與JS互動實戰篇(ObjC版)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.