iOS與Javascript交互實戰(zhàn)

本教程中所涉及到的幾種類型:

JSContext, JSContext是代表JS的執(zhí)行環(huán)境,通過-evaluateScript:方法就可以執(zhí)行一JS代碼

JSValue, JSValue封裝了JS與ObjC中的對應的類型该园,以及調(diào)用JS的API等

JSExport, JSExport是一個協(xié)議,遵守此協(xié)議洋腮,就可以定義我們自己的協(xié)議塔拳,在協(xié)議中聲明的API都會在JS中暴露出來,才能調(diào)用

ObjC與JS交互方式

通過JSContext,我們有兩種調(diào)用JS代碼的方法:

1陌兑、直接調(diào)用JS代碼

2、在ObjC中通過JSContext注入模型由捎,然后調(diào)用模型的方法

直接調(diào)用JS代碼

// 一個JSContext對象兔综,就類似于Js中的window,

// 只需要創(chuàng)建一次即可。

self.jsContext = [[JSContext alloc] init];

//? jscontext可以直接執(zhí)行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中有很多全局的函數(shù)碌宴,為了防止名字重名杀狡,使用模型的方式是最好不過了。通過我們協(xié)商好的模型名稱贰镣,在JS中直接通過模型來調(diào)用我們在ObjC中所定義的模型所公開的API呜象。

通過注入模型的方式交互

首先,我們需要先定義一個協(xié)議碑隆,而且這個協(xié)議必須要遵守JSExport協(xié)議恭陡。

@protocol JavaScriptObjectiveCDelegate// JS調(diào)用此方法來調(diào)用OC的系統(tǒng)相冊方法

- (void)callSystemCamera;

// 在JS中調(diào)用時,函數(shù)名應該為showAlertMsg(arg1, arg2)

// 這里是只兩個參數(shù)的上煤。

- (void)showAlert:(NSString *)title msg:(NSString *)msg;

// 通過JSON傳過來

- (void)callWithDict:(NSDictionary *)params;

// JS調(diào)用Oc休玩,然后在OC中通過調(diào)用JS方法來傳值給JS。

- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params;

@end

接下來劫狠,我們還需要定義一個模型:// 此模型用于注入JS的模型拴疤,這樣就可以通過模型來調(diào)用方法。@interface HYBJsObjCModel : NSObject@property (nonatomic, weak) JSContext *jsContext;

@property (nonatomic, weak) UIWebView *webView;

@end

實現(xiàn)這個模型:

@implementation HYBJsObjCModel

- (void)callWithDict:(NSDictionary *)params {

NSLog(@"Js調(diào)用了OC的方法独泞,參數(shù)為:%@", params);

}

// Js調(diào)用了callSystemCamera

- (void)callSystemCamera {

NSLog(@"JS調(diào)用了OC的方法呐矾,調(diào)起系統(tǒng)相冊");

// JS調(diào)用后OC后,又通過OC調(diào)用JS懦砂,但是這個是沒有傳參數(shù)的

JSValue *jsFunc = self.jsContext[@"jsFunc"];

[jsFunc callWithArguments:nil];

}

- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params {

NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params);

// 調(diào)用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"];

// 通過模型調(diào)用方法罚随,這種方式更好些。

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,不帶參數(shù)弥激。

另一個是jsParamFunc进陡,帶一個參數(shù)。

接下來微服,我們在html中的body中添加以下代碼:

Test how to use objective-c call js

現(xiàn)在就可以測試代碼了趾疚。當我們點擊第一個按鈕:Call ObjC system camera時,通過OCModel.callSystemCamera(),就可以在HTML中通過JS調(diào)用OC的方法糙麦。在OC代碼中辛孵,我們的callSystemCamera方法體中,添加了以下兩行代碼赡磅,就是獲取HTML中所定義的JS就去jsFunc魄缚,然后調(diào)用它。 JSValue *jsFunc = self.jsContext[@"jsFunc"]; [jsFunc callWithArguments:nil];這樣就可以在JS調(diào)用OC方法時焚廊,也讓OC反饋給JS冶匹。看看下面?zhèn)髯值鋮?shù):

- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params { NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params); // 調(diào)用JS的方法 JSValue *jsParamFunc = self.jsContext[@"jsParamFunc"]; [jsParamFunc callWithArguments:@[@{@"age": @10, @"name": @"lili", @"height": @158}]];}獲取我們在HTML中定義的jsParamFunc方法咆瘟,然后調(diào)用它并傳了一個字典作為參數(shù)嚼隘。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市袒餐,隨后出現(xiàn)的幾起案子飞蛹,更是在濱河造成了極大的恐慌,老刑警劉巖灸眼,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卧檐,死亡現(xiàn)場離奇詭異,居然都是意外死亡焰宣,警方通過查閱死者的電腦和手機霉囚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宛徊,“玉大人,你說我怎么就攤上這事逻澳≌⑻欤” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵斜做,是天一觀的道長苞氮。 經(jīng)常有香客問我,道長瓤逼,這世上最難降的妖魔是什么笼吟? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮霸旗,結(jié)果婚禮上贷帮,老公的妹妹穿的比我還像新娘。我一直安慰自己诱告,他們只是感情好撵枢,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般锄禽。 火紅的嫁衣襯著肌膚如雪潜必。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天沃但,我揣著相機與錄音磁滚,去河邊找鬼。 笑死宵晚,一個胖子當著我的面吹牛垂攘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坝疼,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼搜贤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了钝凶?” 一聲冷哼從身側(cè)響起仪芒,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耕陷,沒想到半個月后掂名,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡哟沫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年饺蔑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗜诀。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡猾警,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出隆敢,到底是詐尸還是另有隱情发皿,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布拂蝎,位于F島的核電站穴墅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏温自。R本人自食惡果不足惜玄货,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悼泌。 院中可真熱鬧松捉,春花似錦、人聲如沸馆里。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至以舒,卻和暖如春趾痘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蔓钟。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工永票, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滥沫。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓侣集,卻偏偏與公主長得像,于是被迫代替她去往敵國和親兰绣。 傳聞我的和親對象是個殘疾皇子世分,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 因為項目需要做一個活動,而這個活動的信息是源于HTML5寫的缀辩,而這個操作網(wǎng)頁的過程上臭埋, 是需要到與原生APP這邊交...
    貝勒老爺閱讀 455評論 3 5
  • 前言 ObjectiveC與Js交互是常見的需求,可對于新手或者所謂的高手而言臀玄,其實并不是那么簡單明了瓢阴。這里只介紹...
    一路向北客閱讀 366評論 0 4
  • 隨著H5技術的興起,在iOS開發(fā)過程中健无,難免會遇到原生應用需要和H5頁面交互的問題荣恐。其中會涉及方法調(diào)用及參數(shù)傳值等...
    Chris_js閱讀 3,062評論 1 8
  • 跟原生開發(fā)相比,H5的開發(fā)相對來一個成熟的框架和團隊來講在開發(fā)速度和開發(fā)效率上有著比原生很大的優(yōu)勢累贤,至少不用等待審...
    大沖哥閱讀 1,834評論 0 7
  • 曾經(jīng)服務的一家公司叠穆,在每年年終績效考核的時候,有一項關于Self awareness的評分臼膏。當時覺得這一項設置很可...
    莊艷Ellen閱讀 465評論 0 50