OC中WKWebView与js的交互

作者: AgoniNemo | 来源:发表于2017-02-05 18:16 被阅读3839次

    之前用UIWebView的时候,非常的爽,用JSContext这个类就可以做想做的事,现在要改成WKWebView就比较的坑爹了(这是为什么博主要换控件的原因),因为博主需要在页面文件加载之前就把参数给到web端(js调用有返回值oc方法)。把WKWebView的所以代理方法都看了一遍,发现只有下面方式能与js交互:

    window.webkit.messageHandlers.<name>.postMessage();

    但是这个是没有返回值的,于是博主又想到了。如果让web端用这个方法来通知博主这边,再通过博主这边调用web端,这样好像是可以的,但遗憾的是web端通知了博主以后,是不会停止运行的,还是会走下去的,所以当博主再调用web端传参数时,这是没有意义了。后来博主又想到,是不是可以让web端通知博主后阻塞,然后当博主传完参数再执行下去,最后web端童鞋说很麻烦,就没有动了。想了好长一段时间,才想到是不是可以在web端页面加载前,博主就把参数传到浏览器的一个地方,然后web端去浏览器的那个地方取就行了。于是有了下面的写法:

    要注意的地方是injectionTime,别弄错了 WeakScriptMessageDelegate.h文件 WeakScriptMessageDelegate.m文件

    localStorage这个是网页的本地存储(H5的新东西),相当于iOS的NSUserDefaults,不过大小一般只有5M,这个与浏览器有关。accessToken这个是与web端约定参数key,当然你也可以像下面这样写:

    localStorage["accessToken"] = "74851c23358c";
    localStorage.accessToken ="74851c23358c";

    博主的写法是官方推荐的,反正官方说的,就按照官方的写咯。想了解更多的localStorage的知识,点这里

    PS:如果大家有更好的方法,可以在评论里写出来,或者私信博主,想要demo的点这里

    相关文章

      网友评论

      • 米诺001:楼主,你好,如果需要调用一个带返回值,并且带参数的方法呢,js传给我们一个值,客户端再根据这个值做处理然后返回js一个返回值,这种情况就没办法提前注入了,有没有解决办法呢
        迷了jiang:我们是oc又调用了一次js,你们是怎么解决的。
      • NightFaded:能不能传多个值呢
        NightFaded:@AgoniNemo 好的
        AgoniNemo:可以,你可以弄个json保存
      • UncleFool:楼主,我和你遇到了同一个问题,开始的解决思路也一样。localStorage有没有替换方案,前端同事说看不懂。
        UncleFool:@AgoniNemo 现在还有一个问题,我在原生页面登录后,需要对H5页面刷新,我清了cookie重新请求了H5页面,但是仍然提示去登录。
        UncleFool:@AgoniNemo 同事已经解决了,我和你遇到的问题一样一样的:smile:
        AgoniNemo:@UncleFool :joy: 这有什么看懂的,你可以下我的demo看下,我在里面写了本地的web.其他的替换方案都比较的麻烦,这是比较简单的一种,没要怎么写代码.
      • 来呀快活呀哈哈:博主 我现在也遇到这样的问题,我现在用的是WebViewJavascriptBridge框架,如果坚持用这个库该如何解决这样的问题呢? 我用的是wkwebview。
        AgoniNemo:@来呀快活呀哈哈 如果是和我的问题一样,可以按照文章说的思路去做
      • 16f351940212:楼主,知道oc怎么调web端方法吗? [self.wkWebView evaluateJavaScript:alert() completionHandler:^(id _Nullable response, NSError * _Nullable error) {
        NSLog(@"response: %@ \n error: %@", response, error);

        }]; 这个方法怎么不走
        SoldOut:要想显示alert 还需要实现几个代理方法。
        AgoniNemo::joy: WK会拦截alert方法
      • 聪zero:博主,请教个问题,我们是用cordova做混合app,html,js什么都放在手机本地的,也是用vue的,然后wkwebview经常会白屏,比如你拍个照片,录个视频回来发现web页面白屏了,锁屏一段时间回来发现又白屏了,你有什么解决的办法吗,困扰很久了
        AgoniNemo:@聪zero 你可以试试在刷新前把数据保存下来
        聪zero:@AgoniNemo 不是,百度找了好久,包括stackover上也有人有类似的问题,都说是拍照调用相机,导致内存吃急,wkwebview进程崩溃,所以只能刷新页面,可是我们app一刷新,原有页面数据就都没了,很麻烦不能刷新
        AgoniNemo:@聪zero 感觉不是Vue的问题,你用safari调试下看看,是不是数据发生了什么造成的变化.vue说白了只是数据的绑定,如果你的数据是空,绑定的组件也是跟着变化
      • Kion_:谢谢,的确用着了!
      • Hiker5:额,博主有没有小demo啊?现在也遇到这个问题,然后,你们当初为什么没有用WebViewJavascriptBridge这个啊?
        AgoniNemo:@Hiker5 不用这个也还有另外的原因,就是有坑的话就找起来就很困难了
        Hiker5:@AgoniNemo :flushed: ok,是,看了一下,毕竟9000+star,还找到一个这个https://github.com/wendux/DSBridge-IOS 好像还不错。
        AgoniNemo:demo已经在文章里了,WebViewJavascriptBridge这个库使用起来非常的麻烦,而且满足不了我们的需求。
      • 王_a5ee:我想问下根据你之前文章中iOS.getWebMsg();这种调用,使用WKWebView因该怎么兼容呢,WKWebView中我只找到了window.webkit.messageHandlers.<name>.postMessage();这样的js调用,如果js方法为iOS.getWebMsg()这样的调用,WKWebView中应该怎么实现呢?谢谢
        AgoniNemo:@王_a5ee 那web那边就要一个个去改了,WK只能这么玩
        王_a5ee:@AgoniNemo 我的意思是如果web端的js方法为iOS.getWebMsg()这种,有可能有N多方法iOS.a、iOS.b、iOS.c。。。这样的,如何兼容,因为我之前用UIWebView是这样子来调用的,结果返现WK在web端只能这么玩window.webkit.messageHandlers.<name>.postMessage(),这就悲剧了。。。:scream:
        AgoniNemo:在WKWebView中,是不允许有返回值的调用的,只能通过预先设置localStorage达到效果,没有返回值的方法调用,在web端window.webkit.messageHandlers.<name>.postMessage(),发送通知,在它的代理方法,- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message实现
      • 43b86d3b5040:那如果是运行中需要调用到带返回值的OC函数呢?怎么解决?
        AgoniNemo:@起个名好难_334a 这个很简单,当h5上的点击事件被激发时,让写web的兄弟加个通过window.webkit.messageHandlers.<name>.postMessage();给你发通知,然后,你在- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message方法里判断跳转就行了。如果你不想麻烦写web的兄弟,你也可以在创建wkwebview的时候,通过js给web加上事件。
        16f351940212:你好我遇到的情况跟你一样,我用wkweb与js交互,但是我怎么获取到点击h5端,跳转到我原生的界面
        AgoniNemo:只能通过web通知app,再把值设置到web里

      本文标题:OC中WKWebView与js的交互

      本文链接:https://www.haomeiwen.com/subject/bfbeittx.html