iOS下JS與OC的相互調(diào)用

使用UIWebView,多少免不了要涉及一些JS與原生OC交互日矫,今天就來總結(jié)一下兩種交互方式吧茵汰。

在講述之前枢里,先寫好了一個html的文件,并放入項目中:

<html>
    <header>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <script type="text/javascript">

            function secondClick() {
                share('分享的標題','分享的內(nèi)容','圖片地址');
            }
            
            //剛方法會卡死界面
            function showAlert(message){
                alert(message);
            }
            //不會卡死界面
            function asyncAlert(content) {
                setTimeout(function() {
                   alert(content);
                }, 1);
            }
        </script>
    </header>

    <body>
        <h2> 這里是第二種方式 </h2>
        <br/>
        <br/>
        <button type="button" onclick="secondClick()">Click Me!</button>
    </body>
</html>

在上面的代碼片段中,可以看到j(luò)s中有兩個方法栏豺,一個是secondClick彬碱,一個是showAlert;
可以看出secondClick方法** 又 **調(diào)用了原生OC的方法;

一奥洼、JS調(diào)用原生OC篇

既然是JS調(diào)用原生的OC方法巷疼,那OC方法肯定沒有在JS文件中實現(xiàn),我們需要先實現(xiàn)原生方法灵奖。

  1. 引入#import <JavaScriptCore/JavaScriptCore.h>的頭文件嚼沿。
  2. 在webViewDidFinishLoad方法中添加如下代碼(必須是在這個方法里面添加):
-(void)webViewDidFinishLoad:(UIWebView *)webView {
    //調(diào)用JS中已經(jīng)寫好的方法
    dispatch_async(dispatch_get_main_queue(), ^{
        JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        NSString *textJS = @"showAlert('恭喜發(fā)財')";
        [context evaluateScript:textJS];
    });
    
    //實現(xiàn)JS中聲明的方法
    dispatch_async(dispatch_get_main_queue(), ^{
        JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        context[@"share"] = ^() {
            NSLog(@"================Begin==============");
            
            NSArray *args = [JSContext currentArguments];
            NSLog(@"參數(shù)為:%@", args);
            
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"標題啦" message:@"消息啦" preferredStyle:UIAlertControllerStyleAlert];
            
            UIAlertAction *action = [UIAlertAction actionWithTitle:@"好的啊" style:UIAlertActionStyleDefault handler:nil];
            
            [alert addAction:action];
            [self presentViewController:alert animated:YES completion:nil];
            
            for (JSValue *jsVal in args) {
                NSLog(@"&&&:%@", jsVal.toString);
            }
            
            NSLog(@"-------------End--------------");
        };
    });
}

二、OC調(diào)用原生JS篇

方式一

NSString *jsStr = [NSString stringWithFormat:@"showAlert('%@')",@"這里是JS中alert彈出的message"];
[_webView stringByEvaluatingJavaScriptFromString:jsStr];

注意:該方法會同步返回一個字符串瓷患,因此是一個同步方法骡尽,可能會阻塞UI。

方式二

JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
NSString *textJS = @"showAlert('這里是JS中alert彈出的message')";
[context evaluateScript:textJS];

重點:
stringByEvaluatingJavaScriptFromString是一個同步的方法擅编,使用它執(zhí)行JS方法時攀细,如果JS 方法比較耗的時候,會造成界面卡頓沙咏。尤其是js 彈出alert 的時候辨图。
alert 也會阻塞界面,等待用戶響應(yīng)肢藐,而stringByEvaluatingJavaScriptFromString又會等待js執(zhí)行完畢返回。這就造成了死鎖吱韭。
官方推薦使用WKWebViewevaluateJavaScript:completionHandler:代替這個方法吆豹。
其實我們也有另外一種方式,自定義一個延遲執(zhí)行alert 的方法來防止阻塞理盆,然后我們調(diào)用自定義的alert 方法。同理,耗時較長的js 方法也可以放到setTimeout 中秃踩。

function asyncAlert(content) {
    setTimeout(function() {
         alert(content);
     }, 1);
}

參考文章:JS_OC

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尤揣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子姨俩,更是在濱河造成了極大的恐慌蘸拔,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件环葵,死亡現(xiàn)場離奇詭異调窍,居然都是意外死亡,警方通過查閱死者的電腦和手機张遭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門邓萨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事缔恳”ζ剩” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵歉甚,是天一觀的道長万细。 經(jīng)常有香客問我,道長铃芦,這世上最難降的妖魔是什么雅镊? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮刃滓,結(jié)果婚禮上仁烹,老公的妹妹穿的比我還像新娘。我一直安慰自己咧虎,他們只是感情好卓缰,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著砰诵,像睡著了一般征唬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茁彭,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天总寒,我揣著相機與錄音,去河邊找鬼理肺。 笑死摄闸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的妹萨。 我是一名探鬼主播年枕,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼乎完!你這毒婦竟也來了熏兄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤树姨,失蹤者是張志新(化名)和其女友劉穎摩桶,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娃弓,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡典格,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了台丛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耍缴。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡砾肺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出防嗡,到底是詐尸還是另有隱情变汪,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布蚁趁,位于F島的核電站裙盾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏他嫡。R本人自食惡果不足惜番官,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望钢属。 院中可真熱鬧徘熔,春花似錦、人聲如沸淆党。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽染乌。三九已至山孔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間荷憋,已是汗流浹背台颠。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勒庄,地道東北人蓉媳。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像锅铅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子减宣,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

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

  • iOS開發(fā)免不了要與UIWebView打交道盐须,然后就要涉及到JS與原生OC交互,今天總結(jié)一下JS與原生OC交互的兩...
    德山_閱讀 678評論 0 1
  • 隨著H5技術(shù)的興起漆腌,在iOS開發(fā)過程中贼邓,難免會遇到原生應(yīng)用需要和H5頁面交互的問題。其中會涉及方法調(diào)用及參數(shù)傳值等...
    Chris_js閱讀 3,088評論 1 8
  • 今晚沒有加班闷尿,和技術(shù)部的手下一起下班了塑径。想到我要打車,順路載大家吧填具。 路上想到统舀,也許他們已經(jīng)覺得這是理所當(dāng)然了匆骗,因...
    鄧嘉駒Dex閱讀 198評論 0 0
  • 小六的訓(xùn)練營里多了好多伙伴的分享,7月20日晚上分享的嘉賓是李慧彬誉简,網(wǎng)名睡睡睡碉就,辣媽分享的主題是:天生就是多重身份...
    樂活雅閱讀 637評論 0 1
  • 今天上午把房間和洗手間打掃一遍,把書籍整理一下闷串,突然心情明媚了許多瓮钥,有人曾說過,你的房間就是你的生命狀態(tài)烹吵。確實...
    小敏18閱讀 398評論 0 1