iOS與JS交互實戰(zhàn)篇

前言

ObjectiveC與Js交互是常見的需求功氨,可對于新手或者所謂的高手而言镜会,其實并不是那么簡單明了炫刷。這里只介紹iOS7.0后出來的JavaScriptCore framework毕荐。

關于JavaScriptCore

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

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

JSValue, JSValue封裝了JS與ObjC中的對應的類型,以及調用JS的API等

JSExport, JSExport是一個協(xié)議滚粟,遵守此協(xié)議寻仗,就可以定義我們自己的協(xié)議,在協(xié)議中聲明的API都會在JS中暴露出來坦刀,才能調用

ObjC與JS交互方式

通過JSContext愧沟,我們有兩種調用JS代碼的方法:

1、直接調用JS代碼

2鲤遥、在ObjC中通過JSContext注入模型沐寺,然后調用模型的方法

直接調用JS代碼

// 一個JSContext對象,就類似于Js中的window盖奈,// 只需要創(chuàng)建一次即可混坞。self.jsContext= [[JSContext alloc] init];//? jscontext可以直接執(zhí)行JS代碼。[self.jsContextevaluateScript:@"var num = 10"]; [self.jsContextevaluateScript:@"var squareFunc = function(value) { return value * 2 }"];// 計算正方形的面積JSValue *square = [self.jsContextevaluateScript:@"squareFunc(num)"];// 也可以通過下標的方式獲取到方法JSValue *squareFunc =self.jsContext[@"squareFunc"]; JSValue *value = [squareFunc callWithArguments:@[@"20"]];NSLog(@"%@", square.toNumber);NSLog(@"%@", value.toNumber);

這種方式是沒有注入模型到JS中的钢坦。這種方式使用起來不太合適究孕,通常在JS中有很多全局的函數(shù),為了防止名字重名爹凹,使用模型的方式是最好不過了厨诸。通過我們協(xié)商好的模型名稱,在JS中直接通過模型來調用我們在ObjC中所定義的模型所公開的API禾酱。

通過注入模型的方式交互

首先微酬,我們需要先定義一個協(xié)議绘趋,而且這個協(xié)議必須要遵守JSExport協(xié)議。

@protocolJavaScriptObjectiveCDelegate// JS調用此方法來調用OC的系統(tǒng)相冊方法- (void)callSystemCamera;// 在JS中調用時颗管,函數(shù)名應該為showAlertMsg(arg1, arg2)// 這里是只兩個參數(shù)的陷遮。- (void)showAlert:(NSString*)title msg:(NSString*)msg;// 通過JSON傳過來- (void)callWithDict:(NSDictionary*)params;// JS調用Oc,然后在OC中通過調用JS方法來傳值給JS垦江。- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary*)params;@end

接下來帽馋,我們還需要定義一個模型:

// 此模型用于注入JS的模型,這樣就可以通過模型來調用方法比吭。@interfaceHYBJsObjCModel:NSObject@property(nonatomic,weak) JSContext *jsContext;@property(nonatomic,weak)UIWebView*webView;@end

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

@implementationHYBJsObjCModel- (void)callWithDict:(NSDictionary*)params {NSLog(@"Js調用了OC的方法绽族,參數(shù)為:%@", params);}// Js調用了callSystemCamera- (void)callSystemCamera {NSLog(@"JS調用了OC的方法,調起系統(tǒng)相冊");// JS調用后OC后梗逮,又通過OC調用JS项秉,但是這個是沒有傳參數(shù)的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:nilcancelButtonTitle:@"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方法:

varjsFunc =function(){alert('Objective-C call js to show alert'); }varjsParamFunc =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調用OC的方法洞翩。

在OC代碼中稽犁,我們的callSystemCamera方法體中,添加了以下兩行代碼骚亿,就是獲取HTML中所定義的JS就去jsFunc已亥,然后調用它。

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

這樣就可以在JS調用OC方法時来屠,也讓OC反饋給JS虑椎。

看看下面?zhèn)髯值鋮?shù):

- (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方法秫舌,然后調用它并傳了一個字典作為參數(shù)。

好了绣檬,就講這么多吧足陨,如果想要Demo源代碼,請到

github:https://github.com/CoderJackyHuang/IOSCallJsOrJsCallIOS

最后編輯于
?著作權歸作者所有,轉載或內(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
  • 正文 為了忘掉前任,我火速辦了婚禮功茴,結果婚禮上庐冯,老公的妹妹穿的比我還像新娘。我一直安慰自己痊土,他們只是感情好肄扎,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赁酝,像睡著了一般犯祠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酌呆,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天衡载,我揣著相機與錄音,去河邊找鬼隙袁。 笑死痰娱,一個胖子當著我的面吹牛弃榨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梨睁,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼鲸睛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了坡贺?” 一聲冷哼從身側響起官辈,我...
    開封第一講書人閱讀 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級特大地震影響呢诬,放射性物質發(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)容

  • 隨著H5技術的興起撑蒜,在iOS開發(fā)過程中他巨,難免會遇到原生應用需要和H5頁面交互的問題。其中會涉及方法調用及參數(shù)傳值等...
    Chris_js閱讀 3,062評論 1 8
  • 本教程中所涉及到的幾種類型: JSContext, JSContext是代表JS的執(zhí)行環(huán)境减江,通過-evaluate...
    貝勒老爺閱讀 858評論 0 5
  • 跟原生開發(fā)相比染突,H5的開發(fā)相對來一個成熟的框架和團隊來講在開發(fā)速度和開發(fā)效率上有著比原生很大的優(yōu)勢,至少不用等待審...
    大沖哥閱讀 1,834評論 0 7
  • 前言 Web 頁面中的 JS 與 iOS Native 如何交互是每個 iOS 猿必須掌握的技能辈灼。而說到 Nati...
    幽城88閱讀 2,198評論 1 8
  • 虛空邊緣份企,內(nèi)域。 “咻巡莹∷局荆” 一名毀滅魔族原本在高速飛行,忽然他身體陡然化作上百道血色流光降宅,分散開前進骂远,大多依舊朝空...
    im喵小姐閱讀 214評論 0 0