UIWebView轉(zhuǎn)WKWebView交互方法統(tǒng)一解決辦法

iOS13發(fā)布了,據(jù)說蘋果開始拒絕使用UIWebView的api應(yīng)用了旦部。

有點(diǎn)慌障涯,由于項(xiàng)目自17年開始就一直用的UIWebView厨内,但UIWebView性能實(shí)在是太差了,進(jìn)幾個(gè)網(wǎng)頁內(nèi)存就飆升茄袖,并且退出頁面VC銷毀了但內(nèi)存還無法降下來操软,首次加載網(wǎng)頁的時(shí)候還會(huì)卡那么一會(huì),只能弄個(gè)假進(jìn)度條宪祥。

雖然中途也一直尋思著升級(jí)到WKWebView聂薪,但奈何項(xiàng)目中業(yè)務(wù)眾多又是分布式的,和js交互的地方也很多蝗羊,而WKWebView和UIWebView的交互方法寫法又不一樣藏澳,前端得區(qū)分是Android還是iOS,所有有交互的地方全要改耀找,要前端配合改的話翔悠,估計(jì)人家也不樂意业崖。

然后就這么一直拖著拖著,直到現(xiàn)在木有辦法了蓄愁,項(xiàng)目這時(shí)候剛好微信支付廢掉了双炕,要升級(jí)發(fā)新版本,跟錢相關(guān)的又刻不容緩撮抓,但又怕這次發(fā)新版由于UIWebView的問題被打回來妇斤,得硬著頭皮上了,必須把這塊硬石頭給啃了丹拯。

說干就干

不要慌站超,一步一步來
先不管交互,先把UIWebView切換到WKWebView咽笼,看看只加載網(wǎng)頁有沒什么問題顷编,再把網(wǎng)頁加載完成之后的一些邏輯移植過來,再把進(jìn)度條加上剑刑,OK,很完美双肤,加載網(wǎng)頁柔順多了施掏,內(nèi)存也降下來了。

不要慌茅糜,接下來七芭,集中精力搞定js和原生的交互

使用UIWebView時(shí),js和原生交互是使用注冊(cè)模型類蔑赘,然后js再通過注冊(cè)的模型類調(diào)用和原生聲明好的交互方法狸驳。比如注冊(cè)的模型名稱為backJSAction,交互方法為- (void)returnPage;缩赛,那么js那邊調(diào)用原生的就是backJSAction.returnPage()

而使用WKWebView時(shí)耙箍,js調(diào)用原生方法就變成了window.webkit.messageHandlers.backJSAction.postMessage();,蛋疼就是在這里酥馍,前端得把以前的交互方式辩昆,全部改成這種,而Android那邊卻還是用上面的交互方式旨袒,這就得區(qū)分是Android還是iOS了(話說前端怎么區(qū)分呢汁针?),就算改了砚尽,那舊版的APP就無法使用了施无,這無疑加大了工作量,并且代價(jià)有點(diǎn)高必孤。

怎么辦猾骡,怎么辦,有沒有一種優(yōu)雅的方式,在不牽動(dòng)前端和Android的情況下卓练,順利的將UIWebView切換到WKWebView隘蝎。

不要慌,開始網(wǎng)上找資料

方法一襟企、通過攔截url參數(shù)方式
需要iOS嘱么、Android、前端都改代碼顽悼,不算嚴(yán)格意義上的js交互曼振,而且交互方法無法返回值,直接pass蔚龙。
方法二冰评、使用第三方框架WebViewJavascriptBridge
此法也需要推翻重來,需要iOS木羹、Android甲雅、前端都改代碼,改動(dòng)成本大坑填,只能作為最后的補(bǔ)救方案抛人。

就這樣完了嗎?不脐瑰,肯定是我搜索的方式不對(duì)(我就納悶了妖枚,這應(yīng)該是很多人都會(huì)碰到的問題,為什么就找不到相關(guān)問題和解決辦法)

不要慌苍在,換個(gè)關(guān)鍵詞繼續(xù)找資料

終于绝页,我仿佛看到了曙光,看到一種截然不同的解決辦法
http://www.reibang.com/p/afc52a5a28db
方法三寂恬、通過注入js腳本的方式续誉,轉(zhuǎn)換js的方法調(diào)用
說白了就是將在js調(diào)用backJSAction.returnPage()方法時(shí),將方法轉(zhuǎn)換成window.webkit.messageHandlers.backJSAction.postMessage()掠剑,這樣就可以調(diào)到原生的交互方法了屈芜,頓時(shí)嘴角一揚(yáng)。

不要慌朴译,先寫個(gè)小demo測試一下
測試了一個(gè)無返回值井佑,無參數(shù)- (void)returnPage;和有參數(shù)- (void)setPageTitle:(NSString *)title;的方法,都很完美眠寿,能調(diào)用到躬翁,心情愉悅。
接著往下測試一個(gè)有返回值- (NSString *)getUserInfo;盯拱,發(fā)現(xiàn)js無法接收到返回值盒发,原來是window.webkit.messageHandlers.xxx是沒有返回值的例嘱,也就是WKWebView不支持返回值的交互方法,WTF?

就這樣涼涼了宁舰?心中頓時(shí)跑過一萬只草泥馬拼卵。冷靜片刻后......

不要慌,查查WKWebView怎么同步返回值蛮艰。

看到的都是通過JS端調(diào)用prompt函數(shù)時(shí)腋腮,觸發(fā)WKWebView的一個(gè)代理方法,在代理方法里原生可以同步返回值給js壤蚜。
http://www.reibang.com/p/5fc4c0c6fbdf

難道要前端把所有有返回值的方法調(diào)用即寡,全部換成prompt函數(shù)?那這樣還是要前端改代碼袜刷,并且區(qū)分iOS和Android聪富,這不是我的初衷,抓狂中.......

不行著蟹,頭有點(diǎn)痛墩蔓,休息一下
想啊想,想啊想萧豆,既然上面能將那么復(fù)雜的方法進(jìn)行轉(zhuǎn)化钢拧,那我是不是可以將js的方法也轉(zhuǎn)換成prompt函數(shù),APP再將返回值給prompt函數(shù)炕横,再將prompt接收到的值返回給原始的js方法,有思路了就是干
prompt函數(shù)可以攜帶兩個(gè)參數(shù)prompt和defaultText葡粒,就將原始js方法名當(dāng)做prompt參數(shù)份殿,傳遞到WKWebView的代理方法,APP就根據(jù)方法名來區(qū)分執(zhí)行不同邏輯
腳本中的寫法:

backJSAction.getUserInfo = function () {
    var r = window.prompt("getUserInfo");
    return r;
}

代理方法中寫法:

#pragma mark ------ WKUIDelegate Delegate -------
// 交互嗽交∏涑埃可輸入的文本。
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler {
    NSLog(@"%@---%@",prompt,defaultText);
    NSString *result = @"";
   if ([prompt isEqualToString:@"getUserInfo"]) {
        result = [self getUserInfo];
    }else if ([prompt isEqualToString:@"getStrSign"]) {
        result = [self getStrSign];
    }
    completionHandler(result);//這里就是要返回給JS的返回值
}

寫完夫壁,測試拾枣,完全ojbk,js交互方法能接收APP返回的值盒让。長吁一口氣梅肤,貌似就這樣完美解決了?哈哈哈哈邑茄,我真特么機(jī)智姨蝴。

繼續(xù)往下測試,當(dāng)測試到這個(gè)交互方法時(shí)- (BOOL)isLogin;肺缕,尼瑪左医,又特么出問題了授帕,代理方法的completionHandler()只能返回字符串類型,不能返回布爾值浮梢。WCCCCCCCCCCCCC跛十,開始懷疑人生了。
哪怕前面解決了99%的問題秕硝,這個(gè)問題不解決芥映,那就全白費(fèi)了。
好在天無絕人之路缝裤,經(jīng)過嘗試屏轰,返回空字符串,js那邊接收到的就是false憋飞,返回非空字符串時(shí)霎苗,js那邊接收到的就是true,即想返回NO和YES榛做,就分別completionHandler(@""),completionHandler(@"1")即可唁盏。

大功告成!六點(diǎn)了下班检眯,放國慶假了厘擂,有時(shí)間再補(bǔ)個(gè)demo

10月15日
demo已補(bǔ)上

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市锰瘸,隨后出現(xiàn)的幾起案子刽严,更是在濱河造成了極大的恐慌,老刑警劉巖避凝,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舞萄,死亡現(xiàn)場離奇詭異,居然都是意外死亡管削,警方通過查閱死者的電腦和手機(jī)倒脓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來含思,“玉大人崎弃,你說我怎么就攤上這事『耍” “怎么了饲做?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長调鬓。 經(jī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
  • 文/蒼蘭香墨 我猛地睜開眼厂庇,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼渠啊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起权旷,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤替蛉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后拄氯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灭返,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有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
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至卷中,卻和暖如春矛双,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蟆豫。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工议忽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人无埃。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓徙瓶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嫉称。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侦镇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

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