UIWebView转WKWebView交互方法统一解决办法

iOS13发布了,据说苹果开始拒绝使用UIWebView的api应用了。

有点慌,由于项目自17年开始就一直用的UIWebView,但UIWebView性能实在是太差了,进几个网页内存就飙升,并且退出页面VC销毁了但内存还无法降下来,首次加载网页的时候还会卡那么一会,只能弄个假进度条。

虽然中途也一直寻思着升级到WKWebView,但奈何项目中业务众多又是分布式的,和js交互的地方也很多,而WKWebView和UIWebView的交互方法写法又不一样,前端得区分是Android还是iOS,所有有交互的地方全要改,要前端配合改的话,估计人家也不乐意。

然后就这么一直拖着拖着,直到现在木有办法了,项目这时候刚好微信支付废掉了,要升级发新版本,跟钱相关的又刻不容缓,但又怕这次发新版由于UIWebView的问题被打回来,得硬着头皮上了,必须把这块硬石头给啃了。

说干就干

不要慌,一步一步来
先不管交互,先把UIWebView切换到WKWebView,看看只加载网页有没什么问题,再把网页加载完成之后的一些逻辑移植过来,再把进度条加上,OK,很完美,加载网页柔顺多了,内存也降下来了。

不要慌,接下来,集中精力搞定js和原生的交互

使用UIWebView时,js和原生交互是使用注册模型类,然后js再通过注册的模型类调用和原生声明好的交互方法。比如注册的模型名称为backJSAction,交互方法为- (void)returnPage;,那么js那边调用原生的就是backJSAction.returnPage()

而使用WKWebView时,js调用原生方法就变成了window.webkit.messageHandlers.backJSAction.postMessage();,蛋疼就是在这里,前端得把以前的交互方式,全部改成这种,而Android那边却还是用上面的交互方式,这就得区分是Android还是iOS了(话说前端怎么区分呢?),就算改了,那旧版的APP就无法使用了,这无疑加大了工作量,并且代价有点高。

怎么办,怎么办,有没有一种优雅的方式,在不牵动前端和Android的情况下,顺利的将UIWebView切换到WKWebView。

不要慌,开始网上找资料

方法一、通过拦截url参数方式
需要iOS、Android、前端都改代码,不算严格意义上的js交互,而且交互方法无法返回值,直接pass。
方法二、使用第三方框架WebViewJavascriptBridge
此法也需要推翻重来,需要iOS、Android、前端都改代码,改动成本大,只能作为最后的补救方案。

就这样完了吗?不,肯定是我搜索的方式不对(我就纳闷了,这应该是很多人都会碰到的问题,为什么就找不到相关问题和解决办法)

不要慌,换个关键词继续找资料

终于,我仿佛看到了曙光,看到一种截然不同的解决办法
https://www.jianshu.com/p/afc52a5a28db
方法三、通过注入js脚本的方式,转换js的方法调用
说白了就是将在js调用backJSAction.returnPage()方法时,将方法转换成window.webkit.messageHandlers.backJSAction.postMessage(),这样就可以调到原生的交互方法了,顿时嘴角一扬。

不要慌,先写个小demo测试一下
测试了一个无返回值,无参数- (void)returnPage;和有参数- (void)setPageTitle:(NSString *)title;的方法,都很完美,能调用到,心情愉悦。
接着往下测试一个有返回值- (NSString *)getUserInfo;,发现js无法接收到返回值,原来是window.webkit.messageHandlers.xxx是没有返回值的,也就是WKWebView不支持返回值的交互方法,WTF?

就这样凉凉了?心中顿时跑过一万只草泥马。冷静片刻后......

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

看到的都是通过JS端调用prompt函数时,触发WKWebView的一个代理方法,在代理方法里原生可以同步返回值给js。
https://www.jianshu.com/p/5fc4c0c6fbdf

难道要前端把所有有返回值的方法调用,全部换成prompt函数?那这样还是要前端改代码,并且区分iOS和Android,这不是我的初衷,抓狂中.......

不行,头有点痛,休息一下
想啊想,想啊想,既然上面能将那么复杂的方法进行转化,那我是不是可以将js的方法也转换成prompt函数,APP再将返回值给prompt函数,再将prompt接收到的值返回给原始的js方法,有思路了就是干
prompt函数可以携带两个参数prompt和defaultText,就将原始js方法名当做prompt参数,传递到WKWebView的代理方法,APP就根据方法名来区分执行不同逻辑
脚本中的写法:

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返回的值。长吁一口气,貌似就这样完美解决了?哈哈哈哈,我真特么机智。

继续往下测试,当测试到这个交互方法时- (BOOL)isLogin;,尼玛,又特么出问题了,代理方法的completionHandler()只能返回字符串类型,不能返回布尔值。WCCCCCCCCCCCCC,开始怀疑人生了。
哪怕前面解决了99%的问题,这个问题不解决,那就全白费了。
好在天无绝人之路,经过尝试,返回空字符串,js那边接收到的就是false,返回非空字符串时,js那边接收到的就是true,即想返回NO和YES,就分别completionHandler(@""),completionHandler(@"1")即可。

大功告成!六点了下班,放国庆假了,有时间再补个demo

10月15日
demo已补上

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容