iOS與H5的交互【W(wǎng)KWebView】

H5因其及時(shí)響應(yīng)的更新速度媲美著需求的速度和較高的趣味性受到越來(lái)越多的用戶的青睞盖矫。目前,大多數(shù)的應(yīng)用中都嵌入了H5击奶。優(yōu)點(diǎn)非常明顯辈双。那么在iOS應(yīng)用中如何嵌入一個(gè)H5,并且和它進(jìn)行交互就成了一個(gè)勢(shì)必要掌握的技術(shù)了柜砾。本文我將結(jié)合我在項(xiàng)目中的一些需求整理出對(duì)應(yīng)的技術(shù)點(diǎn)湃望,僅供參考。

在iOS開發(fā)中痰驱,H5的嵌入可以通過(guò)UIWebView或者WKWebView证芭。這兩個(gè)都是繼承UIView,來(lái)加載web數(shù)據(jù)的類担映。UIWebView是在iOS2的時(shí)候開始使用的废士。特點(diǎn)是加載速度慢,占用內(nèi)存多蝇完,優(yōu)化艱難官硝。WKWebView是在iOS8蘋果新推出的,加載速度快四敞,占用內(nèi)存較少泛源,是一個(gè)不錯(cuò)的選擇。如果想要比較兩者的區(qū)別忿危,您可以選擇一個(gè)網(wǎng)頁(yè)進(jìn)行測(cè)試一下达箍。鑒上所述,我們選擇WKWebView進(jìn)行開發(fā)铺厨。好了缎玫,廢話不多說(shuō)了。

1.WKWebView創(chuàng)建和加載

- (void)createWebView
{
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]
    // 根據(jù)需要去設(shè)置對(duì)應(yīng)的屬性
    WKWebView *webView = [[WKWebView alloc]initWithFrame:self.view.bounds configuration:config];
    webView.navigationDelegate = self;
    [self.view addSubview:webView];    

    NSURL *url = [NSURL URLWithString:self.strURL];
    [self loadWebViewWithURL:url];    // JS調(diào)用OC 添加處理腳本
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Share"];
}

2.JS調(diào)用OC代碼解滓。

  [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Share"];

這是利用WKWebView的一個(gè)新特性MessageHandler來(lái)處理JS調(diào)用原生方法赃磨。要實(shí)現(xiàn)JS調(diào)用iOS原生方法,步驟見下洼裤。

  • 添加<WKScriptMessageHandler>協(xié)議邻辉。讓控制器成為MessageHandler的代理對(duì)象。
  • 對(duì)于監(jiān)聽的方法名要和JS開發(fā)的人商量好腮鞍。這里我們監(jiān)聽的是Share方法值骇,對(duì)于JS開發(fā)的人員必須要以以下方式寫。
   window.webkit.messageHandlers. Share.postMessage(null)
  • 實(shí)現(xiàn)協(xié)議方法移国。在這個(gè)方法里message參數(shù)有一個(gè)屬性body吱瘩。message.body就是JS傳過(guò)來(lái)的參數(shù),可以是字符串迹缀,可以是數(shù)組使碾,也可以是字典蜜徽。通過(guò)message.name判斷可以知道監(jiān)聽的是JS的哪個(gè)方法。
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{    
    if ([message.name isEqualToString:@"Share"]) {
             //TODO
    }
}

至此票摇,JS調(diào)用OC代碼就已完結(jié)拘鞋。是不是很簡(jiǎn)單。另外兄朋,我在網(wǎng)上也看到了不一樣的處理方式掐禁。大家可以參考WebViewJavascriptBridge我覺得寫的比較清楚。本人還沒有嘗試過(guò)這種颅和,如果都嘗試過(guò)的寶寶能不能分享一下兩者的優(yōu)缺點(diǎn)啊傅事。

3. OC調(diào)用JS代碼。

     [self.webView evaluateJavaScript:@"show()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
                //TODO
      }];

相信代碼已經(jīng)看得很清楚啦峡扩。show()就是JS寫的方法蹭越,這個(gè)方法可傳可不傳參數(shù),具體依實(shí)際情況而定教届。另外關(guān)于UIWebView和JS的交互,以下部分僅供參考响鹃。

    JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    context[@"Share"] = ^() {
        NSArray *args = [JSContext currentArguments];
        dispatch_async(dispatch_get_main_queue(), ^{
                //TODO
        });

4. 關(guān)于<WKNavigationDelegate>

網(wǎng)頁(yè)加載開始,結(jié)束案训,失敗這幾個(gè)都特別簡(jiǎn)單买置,我就不贅述了。說(shuō)一下下面這個(gè)協(xié)議方法强霎,這個(gè)方法發(fā)生在頁(yè)面跳轉(zhuǎn)中忿项。WKNavigationActionPolicy是一個(gè)枚舉,WKNavigationActionPolicyAllow表示允許跳轉(zhuǎn)城舞,WKNavigationActionPolicyCancel表示取消跳轉(zhuǎn)轩触。對(duì)了,這里還有一個(gè)補(bǔ)充: scrollView嵌套網(wǎng)頁(yè)和原生view家夺,原生view要根據(jù)網(wǎng)頁(yè)的高度來(lái)布局脱柱。我看到不少的電商應(yīng)用都有這種布局,但在算高度上會(huì)有各種問(wèn)題拉馋,不知道你們有遇見過(guò)榨为?

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    NSString *url = navigationAction.request.URL.absoluteString;
    if(![url isEqualToString:self.strURL]) {
          // 頁(yè)面跳轉(zhuǎn)
    }
    decisionHandler(WKNavigationActionPolicyAllow);
}

5. 關(guān)于< WKUIDelegate >

不知道您有沒有遇見過(guò)JS寫的alert()框在iOS上不彈出。那么您有沒有實(shí)現(xiàn)這些協(xié)議方法呢煌茴。

/// 創(chuàng)建一個(gè)新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
/// 輸入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
/// 確認(rèn)框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
/// 警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler;

6. 獲取網(wǎng)頁(yè)標(biāo)題随闺,網(wǎng)頁(yè)加載進(jìn)度和加載狀態(tài)

這是通過(guò)KVO的方式進(jìn)行監(jiān)聽的。您可以點(diǎn)擊進(jìn)WKWebView的內(nèi)部看一下景馁,他們每個(gè)屬性上面都有很長(zhǎng)的解釋,你不難發(fā)現(xiàn)這一段逗鸣。舉一個(gè)獲取標(biāo)題的例子合住。其他的類似绰精。別忘了,KVO監(jiān)聽在dealloc中移除監(jiān)聽者哦透葛。


8E6F0A58-609E-4093-BD65-F51A10D1703D.png
    [self.webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{  
    if ([keyPath isEqualToString:@"title"]) {
        if (object == self.webView) {
            if(self.navigationController) 
                self.navigationItem.title = self.webView.title;
        }
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

以上就是我個(gè)人對(duì)WKWebView的一些理解笨使。demo就不奉上了,這個(gè)要服務(wù)端配合僚害。因?yàn)槲覍懙腍5基本見不了人硫椰,哈哈,我會(huì)努力的萨蚕!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末粹胯,一起剝皮案震驚了整個(gè)濱河市筝蚕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖懂酱,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異恢暖,居然都是意外死亡蒸走,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門捻艳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)驾窟,“玉大人,你說(shuō)我怎么就攤上這事认轨∩鹇纾” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵好渠,是天一觀的道長(zhǎng)昨稼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)拳锚,這世上最難降的妖魔是什么假栓? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮霍掺,結(jié)果婚禮上匾荆,老公的妹妹穿的比我還像新娘。我一直安慰自己杆烁,他們只是感情好牙丽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兔魂,像睡著了一般烤芦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上析校,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天构罗,我揣著相機(jī)與錄音铜涉,去河邊找鬼。 笑死遂唧,一個(gè)胖子當(dāng)著我的面吹牛芙代,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盖彭,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼纹烹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了召边?” 一聲冷哼從身側(cè)響起铺呵,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掌实,沒想到半個(gè)月后陪蜻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贱鼻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年宴卖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邻悬。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡症昏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出父丰,到底是詐尸還是另有隱情肝谭,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布蛾扇,位于F島的核電站攘烛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏镀首。R本人自食惡果不足惜坟漱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望更哄。 院中可真熱鬧芋齿,春花似錦、人聲如沸成翩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)麻敌。三九已至栅炒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赢赊。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工棒呛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人域携。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鱼喉,于是被迫代替她去往敵國(guó)和親秀鞭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

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