iOS下JS與OC互相調(diào)用(三)--MessageHandler

使用WKWebView的時候误褪,如果想要實現(xiàn)JS調(diào)用OC方法憔儿,除了攔截URL之外医清,還有一種簡單的方式。那就是利用WKWebView的新特性MessageHandler來實現(xiàn)JS調(diào)用原生方法铺罢。

MessageHandler 是什么艇挨?

WKWebView 初始化時,有一個參數(shù)叫configuration韭赘,它是WKWebViewConfiguration類型的參數(shù)缩滨,而WKWebViewConfiguration有一個屬性叫userContentController,它又是WKUserContentController類型的參數(shù)泉瞻。WKUserContentController對象有一個方法- addScriptMessageHandler:name:脉漏,我把這個功能簡稱為MessageHandler。

- addScriptMessageHandler:name:有兩個參數(shù)袖牙,第一個參數(shù)是userContentController的代理對象侧巨,第二個參數(shù)是JS里發(fā)送postMessage的對象。?

所以要使用MessageHandler功能鞭达,就必須要實現(xiàn)WKScriptMessageHandler協(xié)議司忱。?

我們在該API的描述里可以看到在JS中的使用方法:

window.webkit.messageHandlers..postMessage()//其中,就是上面方法里的第二個參數(shù)`name`碉怔。//例如我們調(diào)用API的時候第二個參數(shù)填@"Share"烘贴,那么在JS里就是://window.webkit.messageHandlers.Share.postMessage()//是一個鍵值對,鍵是body撮胧,值可以有多種類型的參數(shù)桨踪。// 在`WKScriptMessageHandler`協(xié)議中,我們可以看到mssage是`WKScriptMessage`類型芹啥,有一個屬性叫body锻离。// 而注釋里寫明了body 的類型:Allowed types are NSNumber, NSString, NSDate, NSArray, NSDictionary, and NSNull.

怎么使用MessageHandler?

1.創(chuàng)建WKWebViewConfiguration對象墓怀,配置各個API對應的MessageHandler汽纠。

WKUserContentController對象可以添加多個scriptMessageHandler。

看了示例代碼傀履,會很容易理解虱朵。示例代碼如下:

WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];

? ? configuration.userContentController = [WKUserContentController new];

? ? [configuration.userContentController addScriptMessageHandler:self name:@"ScanAction"];

? ? [configuration.userContentController addScriptMessageHandler:self name:@"Location"];

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

? ? [configuration.userContentController addScriptMessageHandler:self name:@"Color"];

? ? [configuration.userContentController addScriptMessageHandler:self name:@"Pay"];

? ? [configuration.userContentController addScriptMessageHandler:self name:@"Shake"];

? ? [configuration.userContentController addScriptMessageHandler:self name:@"GoBack"];

? ? [configuration.userContentController addScriptMessageHandler:self name:@"PlaySound"];

? ? WKPreferences *preferences = [WKPreferences new];

? ? preferences.javaScriptCanOpenWindowsAutomatically = YES;

? ? preferences.minimumFontSize = 40.0;

? ? configuration.preferences = preferences;

2.創(chuàng)建WKWebView。

這里沒什么好說的,直接看示例代碼吧:

self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];

? ? NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil];

? ? NSURL *fileURL = [NSURL fileURLWithPath:urlStr];

? ? [self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];

? ? self.webView.navigationDelegate = self;

? ? self.webView.UIDelegate = self;

? ? [self.view addSubview:self.webView];

3.實現(xiàn)協(xié)議方法碴犬。

我這里實現(xiàn)了兩個協(xié)議絮宁,WKUIDelegate是因為我在JS中彈出了alert 。WKScriptMessageHandler是因為我們要處理JS調(diào)用OC方法的請求服协。?

先看實現(xiàn)協(xié)議方法的示例代碼:

#pragma mark - WKScriptMessageHandler

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{

//? ? message.body? --? Allowed types are NSNumber, NSString, NSDate, NSArray,NSDictionary, and NSNull.

? ? if ([message.name isEqualToString:@"ScanAction"]) {

? ? ? ? NSLog(@"掃一掃");

? ? } else if ([message.name isEqualToString:@"Location"]) {

? ? ? ? [self getLocation];

? ? } else if ([message.name isEqualToString:@"Share"]) {

? ? ? ? [self shareWithParams:message.body];

? ? } else if ([message.name isEqualToString:@"Color"]) {

? ? ? ? [self changeBGColor:message.body];

? ? } else if ([message.name isEqualToString:@"Pay"]) {

? ? ? ? [self payWithParams:message.body];

? ? } else if ([message.name isEqualToString:@"Shake"]) {

? ? ? ? [self shakeAction];

? ? } else if ([message.name isEqualToString:@"GoBack"]) {

? ? ? ? [self goBack];

? ? } else if ([message.name isEqualToString:@"PlaySound"]) {

? ? ? ? [self playSound:message.body];

? ? }

}

WKScriptMessage有兩個關鍵屬性name?和?body绍昂。?

因為我們給每一個OC 方法取了一個name,那么我們就可以根據(jù)name 來區(qū)分執(zhí)行不同的方法偿荷。body 中存著JS 要給OC 傳的參數(shù)窘游。?

關于參數(shù)body 的解析,我就舉一個body中放字典的例子跳纳,其他的稍后可以看demo忍饰。?

解析JS 調(diào)用OC 實現(xiàn)分享的參數(shù):

- (void)shareWithParams:(NSDictionary *)tempDic

{

? ? if (![tempDic isKindOfClass:[NSDictionary class]]) {

? ? ? ? return;

? ? }

? ? NSString *title = [tempDic objectForKey:@"title"];

? ? NSString *content = [tempDic objectForKey:@"content"];

? ? NSString *url = [tempDic objectForKey:@"url"];

? ? // 在這里執(zhí)行分享的操作? ? // 將分享結果返回給js? ? NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];

? ? [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {

? ? ? ? NSLog(@"%@----%@",result, error);

? ? }];

}

message.boby 就是JS 里傳過來的參數(shù)。我們不同的方法先做一下容錯性判斷寺庄。然后正常取值就可以了喘批。

4.處理HTML中JS調(diào)用。

HMTL的源碼跟之前的HTML內(nèi)容差不多铣揉,只有JS的調(diào)用部分改變了饶深。

// 傳nullfunctionscanClick(){ window.webkit.messageHandlers.ScanAction.postMessage(null);

}// 傳字典? ? ? ? ? ? ? functionshareClick(){? ? window.webkit.messageHandlers.Share.postMessage({title:'測試分享的標題',content:'測試分享的內(nèi)容',url:'http://www.baidu.com'});

}// 傳字符串functionplaySound(){

? ? window.webkit.messageHandlers.PlaySound.postMessage('shake_sound_male.wav');

}// 傳數(shù)組functioncolorClick(){? ? window.webkit.messageHandlers.Color.postMessage([67,205,128,0.5]);

}

5.OC調(diào)用JS

這里使用WKWebView 實現(xiàn)OC 調(diào)用JS方法跟上一篇是一樣的,還是利用?

- evaluateJavaScript:completionHandler:逛拱。像下面這樣使用:

// 將分享結果返回給js NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];

? ? [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {

? ? ? ? NSLog(@"%@----%@",result, error);

? ? }];

使用MessageHandler 的好處

1.在JS中寫起來簡單敌厘,不用再用創(chuàng)建URL的方式那么麻煩了。

2.JS傳遞參數(shù)更方便朽合。使用攔截URL的方式傳遞參數(shù)俱两,只能把參數(shù)拼接在后面,如果遇到要傳遞的參數(shù)中有特殊字符曹步,如&宪彩、=、讲婚?等尿孔,必須得轉換,否則參數(shù)解析肯定會出錯筹麸。?

例如傳遞的url是這樣的:?

http://www.baidu.com/share/openShare.htm?share_uuid=shdfxdfdsfsdf&name=1234556?

使用攔截URL 的JS調(diào)用方式

loadURL("haleyAction://shareClick?title=分享的標題&content=分享的內(nèi)容&url=鏈接地址&imagePath=圖片地址"); }

將上面的url 放入鏈接地址這里后活合,根本無法區(qū)分share_uuid是其他參數(shù),還是url里附帶的參數(shù)物赶。?

但是使用MessageHandler 就可以避免特殊字符引起的問題白指。

效果圖

更詳細的使用步驟還是去工程中查看吧。地址:JS_OC_MessageHandler

版權聲明:本文為博主原創(chuàng)文章酵紫,轉載請注明出處告嘲。 https://blog.csdn.net/u011619283/article/details/52135988

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末错维,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子橄唬,更是在濱河造成了極大的恐慌需五,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轧坎,死亡現(xiàn)場離奇詭異,居然都是意外死亡泽示,警方通過查閱死者的電腦和手機缸血,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來械筛,“玉大人捎泻,你說我怎么就攤上這事÷裼矗” “怎么了笆豁?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赤赊。 經(jīng)常有香客問我闯狱,道長,這世上最難降的妖魔是什么抛计? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任哄孤,我火速辦了婚禮,結果婚禮上吹截,老公的妹妹穿的比我還像新娘瘦陈。我一直安慰自己,他們只是感情好波俄,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布晨逝。 她就那樣靜靜地躺著,像睡著了一般懦铺。 火紅的嫁衣襯著肌膚如雪捉貌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天冬念,我揣著相機與錄音昏翰,去河邊找鬼。 笑死刘急,一個胖子當著我的面吹牛棚菊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播叔汁,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼统求,長吁一口氣:“原來是場噩夢啊……” “哼检碗!你這毒婦竟也來了?” 一聲冷哼從身側響起码邻,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤折剃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后像屋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怕犁,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年己莺,在試婚紗的時候發(fā)現(xiàn)自己被綠了奏甫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡凌受,死狀恐怖阵子,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胜蛉,我是刑警寧澤挠进,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站誊册,受9級特大地震影響领突,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜案怯,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一攘须、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧殴泰,春花似錦于宙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至离咐,卻和暖如春谱俭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宵蛀。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工昆著, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人术陶。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓凑懂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親梧宫。 傳聞我的和親對象是個殘疾皇子接谨,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

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