OC與JS之間的互調(diào)


一、JavaScriptCore常用的類

JavaScriptCore作用:JavaScriptCore是蘋果原生API淆攻,用來(lái)JS和OC交互的。

JSContext: JS運(yùn)行環(huán)境,用它去執(zhí)行JS代碼蒲牧,并且通過(guò)它去獲取JS里的數(shù)據(jù)

JSValue: 用于接收J(rèn)S中獲取的數(shù)據(jù)類型也榄,可以是任一對(duì)象巡莹,方法。

二甜紫、OC調(diào)用JS

本質(zhì):JS代碼中已經(jīng)定義好變量和方法降宅,通過(guò)OC去獲取,并且調(diào)用

步驟:

1.創(chuàng)建JS運(yùn)行環(huán)境

2.執(zhí)行JS代碼

3.獲取JS數(shù)據(jù)(變量囚霸,方法)

4.使用JS數(shù)據(jù)腰根,方法

2.1 獲取定義在JS中的變量

可以直接通過(guò)OC修改JS中變量的值

#pragma mark - 獲取JS中定義的變量

- (void)getJSVar{

// JS代碼

NSString *jsCode = @"var arr = [1,2,3]";

// 創(chuàng)建JS運(yùn)行環(huán)境

JSContext *ctx = [[JSContext alloc] init];

// 執(zhí)行JS代碼

[ctx evaluateScript:jsCode];

// 因?yàn)樽兞恐苯佣x在JS中,所以可以直接通過(guò)JSContext獲取邮辽,根據(jù)變量名稱獲取唠雕,相當(dāng)于字典的Key

// 只有先執(zhí)行JS代碼贸营,才能獲取變量

JSValue *jsArr = ctx[@"arr"];?

? jsArr[0] = @5;

// 打印結(jié)果:5,2,3

NSLog(@"%@",jsArr);}

2.2 獲取定義在JS中的方法,并且調(diào)用

實(shí)現(xiàn)OC調(diào)用JS方法

#pragma mark - OC調(diào)用JS

// OC調(diào)用JS方法岩睁,并獲取返回結(jié)果

- (void)ocCallJSFunc{

NSString *jsCode =@"function hello(say){"

" return say; "

"}";

// 創(chuàng)建JS運(yùn)行環(huán)境

JSContext *ctx = [[JSContext alloc] init];

// 因?yàn)榉椒ㄖ苯佣x在JS中钞脂,所以可以直接通過(guò)JSContext獲取,根據(jù)方法名稱獲取捕儒,相當(dāng)于字典的Key

// 執(zhí)行JS代碼

[ctx evaluateScript:jsCode];

// 獲取JS方法冰啃,只有先執(zhí)行JS代碼,才能獲取

JSValue *hello = ctx[@"hello"];

// OC調(diào)用JS方法刘莹,獲取方法返回值

JSValue *result = [hello callWithArguments:@[@"你好"]];

// 打印結(jié)果:你好

NSLog(@"%@",result);

}

三阎毅、JS調(diào)用OC中的block

本質(zhì):一開始JS中并沒(méi)有OC的block,所以沒(méi)法直接調(diào)用OC的block点弯,需要把OC的block扇调,在JS中生成方法,然后在通過(guò)JS調(diào)用抢肛。

步驟:

1.創(chuàng)建JS運(yùn)行環(huán)境

2.在JS中生成對(duì)應(yīng)的OC代碼

3.使用JS調(diào)用狼钮,在JS環(huán)境中生成的block方法,就能調(diào)用到OC的block中.

3.1 JS調(diào)用OC中不帶參數(shù)的block

想通過(guò)JS調(diào)用OC中不帶參數(shù)的block

#pragma mark - JS調(diào)用OC中不帶參數(shù)的block

- (void)jsCallOCBlock1WithNoneArguments{

// 創(chuàng)建JS運(yùn)行環(huán)境

JSContext *ctx = [[JSContext alloc] init];

// JS調(diào)用Block方式// 由于JS本身沒(méi)有OC這個(gè)代碼捡絮,需要給JS中賦值熬芜,就會(huì)自動(dòng)生成右邊的代碼.

// 相當(dāng)于在JS中定義一個(gè)叫eat的方法,eat的實(shí)現(xiàn)就是block中的實(shí)現(xiàn)福稳,只要調(diào)用eat,就會(huì)調(diào)用block

ctx[@"eat"] = ^(){NSLog(@"吃東西");?

? };

// JS執(zhí)行代碼涎拉,就會(huì)直接調(diào)用到block中

NSString*jsCode =@"eat()";?

? [ctx evaluateScript:jsCode];}

3.2 JS調(diào)用OC中帶參數(shù)的block

想通過(guò)JS調(diào)用OC中帶參數(shù)的block

- (void)jsCallOCBlockWithArguments{

// 創(chuàng)建JS運(yùn)行環(huán)境

JSContext *ctx = [[JSContext alloc] init];

// 2.調(diào)用帶有參數(shù)的block

// 還是一樣的寫法,會(huì)在JS中生成eat方法的圆,只不過(guò)通過(guò)[JSContext currentArguments]獲取JS執(zhí)行方法時(shí)的參數(shù)

ctx[@"eat"] = ^(){

// 獲取JS調(diào)用參數(shù)

NSArray *arguments = [JSContext currentArguments];

NSLog(@"吃%@",arguments[0]);?

? };

// JS執(zhí)行代碼,調(diào)用eat方法鼓拧,并傳入?yún)?shù)面包

NSString*jsCode =@"eat('面包')";?

? [ctx evaluateScript:jsCode];

}

四、JS調(diào)用OC中的類

本質(zhì):一開始JS中并沒(méi)有OC的類略板,需要先在JS中生成OC的類毁枯,然后在通過(guò)JS調(diào)用。

步驟

1.OC類必須遵守JSExport協(xié)議叮称,只要遵守JSExport協(xié)議种玛,JS才會(huì)生成這個(gè)類

2.但是還不夠,類里面有屬性和方法瓤檐,也要在JS中生成

3.JSExport本身不自帶屬性和方法赂韵,需要自定義一個(gè)協(xié)議,繼承JSExport挠蛉,在自己的協(xié)議中暴露需要在JS中用到的屬性和方法

4.這樣自己的類只要繼承自己的協(xié)議就好祭示,JS就會(huì)自動(dòng)生成類,包括自己協(xié)議中聲明的屬性和方法

4.1 JS調(diào)用OC自定義類

自定義協(xié)議(PersonJSExport)

@protocolPersonJSExport

@property(nonatomic, strong) NSString *name;

-(void)play;

// 調(diào)用多個(gè)參數(shù)的方法谴古,JS函數(shù)命名規(guī)則和OC還不一樣质涛,很可能調(diào)用不到對(duì)應(yīng)的JS生成的函數(shù)稠歉,為了保證生成的JS函數(shù)和OC方法名一致,OC提供了一個(gè)宏JSExportAs汇陆,用來(lái)告訴JS應(yīng)該生成什么樣的函數(shù)對(duì)應(yīng)OC的方法怒炸,這樣就不會(huì)調(diào)錯(cuò)了。

// PropertyName:JS函數(shù)生成的名字

// Selector:OC方法名

// JS就會(huì)自動(dòng)生成playGame這個(gè)方法JSExportAs(playGame,

- (void)playWithGame:(NSString *)gametime:(NSString *)time);

@end

自定義類(Person)

@interfacePerson: NSObject

@property(nonatomic, strong) NSString *name;

-(void)playWithGame:(NSString*)gametime:(NSString*)time;

@end

@implementationPerson

-(void)play{

NSLog(@"%@玩",_name);

}

-(void)playWithGame:(NSString*)gametime:(NSString*)time{

NSLog(@"%@在%@玩%@",_name,time,game);

}

@end

通過(guò)JS調(diào)用OC自定義類

#pragmamark - JS調(diào)用OC自定義類

- (void)jsCallOCCustomClass{

// 創(chuàng)建Person對(duì)象

Person *p = [[Person alloc] init];? ?

p.name = @"zs";? ?

JSContext *ctx = [[JSContext alloc] init];

// 會(huì)在JS中生成Person對(duì)象毡代,并且擁有所有值

// 前提:Person對(duì)象必須遵守JSExport協(xié)議阅羹,

ctx[@"person"] = p;

// 執(zhí)行JS代碼

// 注意:這里的person一定要跟上面聲明的一樣,因?yàn)樯傻膶?duì)象是用person引用// NSString *jsCode = @"person.play()";

NSString *jsCode = @"person.playGame('德州撲克','晚上')";?

? [ctx evaluateScript:jsCode];

}

4.1 JS調(diào)用OC系統(tǒng)類

問(wèn)題:系統(tǒng)自帶的類教寂,想要通過(guò)JS調(diào)用怎么辦捏鱼,我們又沒(méi)辦法修改系統(tǒng)自帶類的文件

和調(diào)用自定義類一樣,也要弄個(gè)自定義協(xié)議繼承JSExport,描述需要暴露哪些屬性(想要把系統(tǒng)類的哪些屬性暴露,就在自己的協(xié)議聲明)

通過(guò)runtime,給類添加協(xié)議

自定義協(xié)議(UILabelJSExport)

@protocolUILabelJSExport

@property(nonatomic, strong) NSString *text;

@end

JS調(diào)用OC系統(tǒng)類

#pragma mark - JS調(diào)用OC系統(tǒng)類

- (void)jsCallOCSystemClass{?

? // 給系統(tǒng)類添加協(xié)議 class_addProtocol([UILabel class],

@protocol(UILabelJSExport));?

? // 創(chuàng)建UILabel?

UILabel *label= [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];

[self.view addSubview:label];

JSContext *ctx = [[JSContext alloc] init];? ?

// 就會(huì)在JS中生成label對(duì)象晚岭,并且用laebl引用

ctx[@"label"] =label;

// 利用JS給label設(shè)置文本內(nèi)容

NSString *jsCode = @"label.text = 'Oh Year'";?

? [ctx evaluateScript:jsCode];

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市问潭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌婚被,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,657評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梳虽,死亡現(xiàn)場(chǎng)離奇詭異址芯,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)窜觉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,662評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門谷炸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人禀挫,你說(shuō)我怎么就攤上這事旬陡。” “怎么了语婴?”我有些...
    開封第一講書人閱讀 158,143評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵描孟,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我砰左,道長(zhǎng)匿醒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,732評(píng)論 1 284
  • 正文 為了忘掉前任缠导,我火速辦了婚禮廉羔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘僻造。我一直安慰自己憋他,他們只是感情好孩饼,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,837評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著竹挡,像睡著了一般镀娶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上此迅,一...
    開封第一講書人閱讀 50,036評(píng)論 1 291
  • 那天汽畴,我揣著相機(jī)與錄音,去河邊找鬼耸序。 笑死忍些,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的坎怪。 我是一名探鬼主播罢坝,決...
    沈念sama閱讀 39,126評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼搅窿!你這毒婦竟也來(lái)了嘁酿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,868評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤男应,失蹤者是張志新(化名)和其女友劉穎闹司,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沐飘,經(jīng)...
    沈念sama閱讀 44,315評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡游桩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,641評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了耐朴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片借卧。...
    茶點(diǎn)故事閱讀 38,773評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖筛峭,靈堂內(nèi)的尸體忽然破棺而出铐刘,到底是詐尸還是另有隱情,我是刑警寧澤影晓,帶...
    沈念sama閱讀 34,470評(píng)論 4 333
  • 正文 年R本政府宣布镰吵,位于F島的核電站,受9級(jí)特大地震影響俯艰,放射性物質(zhì)發(fā)生泄漏捡遍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,126評(píng)論 3 317
  • 文/蒙蒙 一竹握、第九天 我趴在偏房一處隱蔽的房頂上張望画株。 院中可真熱鬧,春花似錦、人聲如沸谓传。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,859評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)续挟。三九已至紧卒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诗祸,已是汗流浹背跑芳。 一陣腳步聲響...
    開封第一講書人閱讀 32,095評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留直颅,地道東北人博个。 一個(gè)月前我還...
    沈念sama閱讀 46,584評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像功偿,于是被迫代替她去往敵國(guó)和親盆佣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,676評(píng)論 2 351

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

  • 項(xiàng)目中涉及OC與網(wǎng)頁(yè)的交互械荷,查找資料時(shí)看到了JavaScriptCore.framework共耍,就對(duì)照文章ios7 ...
    YaoYaoX閱讀 2,334評(píng)論 7 11
  • 隨著H5技術(shù)的興起,在iOS開發(fā)過(guò)程中吨瞎,難免會(huì)遇到原生應(yīng)用需要和H5頁(yè)面交互的問(wèn)題痹兜。其中會(huì)涉及方法調(diào)用及參數(shù)傳值等...
    Chris_js閱讀 3,062評(píng)論 1 8
  • 本文由我們團(tuán)隊(duì)的 糾結(jié)倫 童鞋撰寫。 寫在前面 本篇文章是對(duì)我一次組內(nèi)分享的整理颤诀,大部分圖片都是直接從keynot...
    知識(shí)小集閱讀 15,234評(píng)論 11 172
  • OC 獲取js中的key OC調(diào)用js方法 JS調(diào)用OC中不帶參數(shù)的block JS調(diào)用OC中帶參數(shù)的block ...
    音吹閱讀 423評(píng)論 0 0
  • 寫在前面 本篇文章是對(duì)我一次組內(nèi)分享的整理佃蚜,大部分圖片都是直接從keynote上截圖下來(lái)的,本來(lái)有很多炫酷動(dòng)效的着绊,...
    等開會(huì)閱讀 14,409評(píng)論 6 69