App与Js交互(一)iOS

JavaScript08

App与Js交互(一)iOS,第1张

Demo: https://github.com/gwpp/jsinterface

不论是在创业团队中快速试错,还是在成熟团队中快速迭代复杂需求,还或者是其他原因,WebView在APP中的大量使用已经成为了一个明显的趋势,这也应该算是大前端融合的一个表象吧。笔者在工作中也遇到过很多App&Js交互的问题,粗浅的研究了一下,这里也分享给大家,如果有错误的地方还请下方留言指出,共同进步。

众所周知,iOS有 UIWebView 、 WKWebView 两个组件可以用来渲染嵌入页面。前者使用甚广,出生的也早,后者是iOS8推出的,优化了加载速度和内存,安全性上也有所提升。具体的两者比较百度、上都很多,这里不做赘述。

前两种方法到此就介绍完了,很简单,但是在项目大了之后拦截跳转的代理方法中会有非常多的判断。冗余、可维护性差,硬编码重。所以我们会有下面的其他方法。

JSContext即JavaScriptContext,这个东西在UIWebView中可以拿到,但是在WKWebView中却是取不到了,所以只能用在UIWebView中。除此以外Android里也有类似的一个东西,所以使用JSContext就有了在JS端多平台统一的可能,这里不多说,在《App与Js交互(三)》中会有详细说明。

JSContext的原理就是iOS暴露出去一个遵守 <JSExport>协议的对象给JS,JS可以直接调用该对象的public方法。

window.webkit.messagehandlers.<name>.postMessage 是apple推荐使用的WKWebView的JS交互方式,使用起来比较简单,不支持callback回调。

客户端在做完基本UI界面之后,往往都会向JS与客户端交互上发展,简单来说就是:客户端调用JS方法,JS调用客户端方法,这样做对app灵活性方面有了极大提升。

网上比较好用的第三方框架很多,比较典型的有 webviewJavaScriptBridge ,苹果自iOS7之后推出的一款框架叫 JavaScriptCore

JavaScriptCore 是在webview的didFinishLoad里面注入JS语句,完成两端的相互调用,我查过一些资料,对这个框架用着不舒服,于是就转向了 webviewJavaScriptBridge ,下面我就着重记录一下自己在开发这块功能时候的笔记和想法。

webviewJavaScriptBridge 兼容iOS6之前和之后,同样也兼容了iOS8推出的 WKWebView ,我想用过 WKWebView 的人都知道它比之 UIWebView 的优势, webviewJavaScriptBridge 能兼容 WKWebView 是再好不过了。

往简单了说, webviewJavaScriptBridge 的使用主要是靠 WKWebViewJavascriptBridge 来连接OC端(也即客户端)与JS端,这里我们需要配合服务端来做,规定好方法名,调用 registerHandler 和 callHandler 就可以了。

[self.bridge setWebViewDelegate:self]这个可要可不要,有时候可能需要在webview代理方法中处理一些UI上的显示问题,所以我这里保留了。但是这样的话就可能造成循环引用,因为self持有webview,而webview又持有self,所以我在这里用了weak修饰webview就可以了。

简单来说,在客户端只需要在合适的地方调用

两端的调用总体来说就是这样,是不是很方便呢?注意要和前端同事协调好方法名

1、安装``` npm install jweixin-module --save ```2、创建文件share.wx.js``` // 引入微信jssdk const jweixin = require('jweixin-module') const install = (Vue, vm) =>{// shareInfo: {// title: '标题',// desc: '描述',// link: location.origin,// imgUrl: 'http://admin.djiajia.cn/uploads/wechat_img/2020/07/29/20200729095315-5f20d68b1ea0d.jpg'// }const init = (shareInfo = {}) =>{ // 获取微信jssdk,用于分享 vm.$u.api.getWxjssdk({ url: location.href }).then(res =>{ res = res.data vm.$u.vuex('vuex_wxjssdk', res) console.log(res) jweixin.config({ debug: res.debug, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: res.appId, // 必填,公众号的唯一标识 timestamp: res.timestamp, // 必填,生成签名的时间戳 nonceStr: res.nonceStr, // 必填,生成签名的随机串 signature: res.signature, // 必填,签名 jsApiList: res.jsApiList // 必填,需要使用的JS接口列表 }) jweixin.ready(() =>{ console.log(shareInfo.title) // 分享给朋友 jweixin.updateAppMessageShareData({title: shareInfo.title,desc: shareInfo.desc,link: shareInfo.link,imgUrl: shareInfo.imgUrl,success: () =>{ // 设置成功} }) // 分享到朋友圈 jweixin.updateTimelineShareData({title: shareInfo.title,link: shareInfo.link,imgUrl: shareInfo.imgUrl,success: () =>{ // 设置成功} }) // 分享到朋友圈 jweixin.onMenuShareTimeline({title: shareInfo.title,link: shareInfo.link,imgUrl: shareInfo.imgUrl,success: () =>{} }) // 分享给朋友 jweixin.onMenuShareAppMessage({title: shareInfo.title,desc: shareInfo.desc,link: shareInfo.link,imgUrl: shareInfo.imgUrl,success: () =>{} }) }) jweixin.error(function(res) { // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 console.log(res) })})} // 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下vm.$u.share = { init} } export default {install } ```3、main.js   app.$mount() 上面加入``` // 微信jssdk初始化 import wxshare from '@/common/share.wx.js' Vue.use(wxshare, app) ```4、调用``` this.$u.share.init({ title: '标题', desc: '描述', link: location.origin, imgUrl: '分享图片地址' }) ```