使用微信JSSDK来调用微信组件完成图片的选择展示上传与下载是一个很高效的方式。但是遇到了如下问题。 安卓手机一切正常,可以选择图片,也能根据返回的信息局部更新页面显示预览,但是苹果IOS下选择与上传正常。但是无法显示,通过查阅资料等等大致梳理出问题原因与解决办法。
问题来源
1.首先本来早期的微信图片接口就有一些问题与局限。后面通过更新JSSDK版本到1.2.0的方式,得到了改善与解决。
2.快乐的时光总是短暂的,一段时间后,苹果更新系统到了IOS8了,其中的一个重要变化就是在IOS8中引入了新组件 WKWebView 。
WKWebView 是苹果在iOS 8中引入的新组件,目的是提供一个现代的支持最新Webkit功能的网页浏览控件,摆脱过去 UIWebView的老、旧、笨,特别是内存占用量巨大的问题。它使用与Safari中一样的Nitro JavaScript引擎,大大提高了页面js执行速度
于是我们的微信就屁颠屁颠跟上了
微信iOS客户端将于2017年3月1日前逐步升级为WKWebview内核
于是微信的JSSDK适配又出现了些问题,我猜测就是由于对WKWebview内核的支持或者自动切换内核的兼容问题导致的。体现就是我们上面说的。 在IOS下选择图片接口wx.chooseImage 返回的信息无法直接显示。于是进而WX 也做出了解决方案,挺智障的解决方案。新增了一个wx.getLocalImgData接口 https://mp.weixin.qq.com/wiki?action=doc&id=mp1421141115&t=0.7003026651218534#17
备注:此接口仅在 iOS WKWebview 下提供,用于兼容 iOS WKWebview 不支持 localId 直接显示图片的问题。
为什么说智障呢,这个接口在文章中虽然排序的等级和wx.chooseImage一样,但是不是直接让你去掉用的,因为如果你直接使用这个接口,一样会出现各种BUG。 首先这个接口只适用于特殊情况 苹果IOS 8以上,其次根据我的理解这与其说是一个独立接口, 不如纯粹说这只是一个特殊情况下才去使用的次级接口,完全不应该具备独立接口的位置,文档标志不清极大的干扰了开发者的判断, 而且最后为了配合这个接口又注入了新的 一个函数来做判断
在页面中可通过微信注入的window.wxjs_is_wkwebview变量判断当前使用的webview内核。 iOS微信6.5.3及其之后的版本 window.wxjs_is_wkwebview 为true时是使用WKWebview,为 false或者 “undefine”时是 UIWebview 。。
说人话就是 微信:“我感觉我的chooseImage没啥毛病,但我也没说没毛病,如果你有毛病了,我还提供了一个应急的getLocalImgData 哦,你先用常规的,然后判断下wxjs_is_wkwebview,是的话,就用应急的。最后取回的格式不一样你自己做个适配就好”
说解决方案前吐槽几点:
1.WX你走点心吧,据我所知大部分旧版SDK的程序员基本都不知道JSSDK已经更新,JSSDK升级1.2.0 敢不敢通知得更明显一点,严重滞后
2.其实最佳方式是官方通过升级JSSDK来解决,本身这个问题,概括成一句话就是,在不同的浏览器返回不同的图片格式。以让图片都能适配。 但是官方不愿升级,究其原因大概是因为,为了做向前兼容吧,毕竟前面的版本都是返回固定的格式数据。
3.如果一个要开发者做兼容,敢不敢把范例文档写得清晰一点。个人认为最好是将wx.getLocalImgData接口合并到选择接口里面,不需要单独列出来,因为本身这个接口就没有独立地位,甚至也无需在JSAPI引用列表里申明
4.首先IOS的调试实在是太不友好了,其次这个问题在微信开发者工具中无法调试复现,开发者工具中用官方页面永远只是成功,用实际页面永远返回 WX.getLocalImgData 验证失败。 不仅没有起到参考作用反而直接带偏。
解决方案
根据我的估计,大部分人开发者会遇到以下几个情绪阶段
1.第一次崩溃:JSSDK版本过低导致苹果系统不显示,查阅后发现原来是我的版本低,升级就好,以为解决(这个需要升级,但升级只是必要并非一定能解决,升级能保证选择照片与上传不出问题,但不能保证选择好后系统回传的能被正常显示预览)
2.第二次崩溃:但是忽然可能测试反馈还是不成功,清理缓存等等后发现JSSDK版本已经是1.2.0但苹果依然不显示,开始自我怀疑,再次解决,发现了IOS更新组件进而微信也更新进而出现微信自己说“有可能出问题哦,但出了你要做适配哦”二度崩溃 文档范例的滞后模糊使得虽然发现了新接口。但潜意识都是将wx.getLocalImgData替换掉wx.chooseImage,一番纠结后理解,原来不是替换啊。只是个附属的次级接口。先做个判断才能用
3.第三次崩溃:可能测试一张图片正常但是多张有问题,或者感觉些对了。执行对了,就是无效或者错乱,因为这里有个很肯的小细节,WX.getLocalImgData接口只负责返回新的数据,但是显示层还是用户自己的JS来局部刷新HTML 一般来说,我们常规的写法是统一将所有图片生成一个数组后,循环来更新HTML,没毛病。但是WX.getLocalImgData 是一个异步执行函数,也就是调用后,JS就继续执行下面了,至于这个异步的死活暂时不管。 用原本的代码是一定会出问题的。这里的预览部分的JS代码要重写,换成符合异步的逐步更新HTML的写法。当然这仅仅只是一种思路方法,了解本质后有无数种办法能解决。不管如何,到这里我们就完美解决了!
将具体解决步骤凝练如下:
1.使用最新版本的WX JSSDK 方法
1.2.0以下版本的JSSDK不再支持通过使用chooseImage api返回的localld以如:”img src=wxLocalResource://50114659201332”的方式预览图片。 适配建议:直接将JSSDK升级为1.2.0最新版本即可帮助页面自动适配,但在部分场景下可能无效,此时可以使用 getLocalImgData 接口来直接获取数据。 。(更新版本为1.2.0 ,https://res.wx.qq.com/open/js/jweixin-1.2.0.js )
通过这一步。基本解决部分历史遗留问题。
2.做一下苹果IOS 8以上的兼容适配。
代码核心的思路就是:
wx.chooseImage(/*先正常获取localId */
if{判断是否WKWebview内核
是这个内核于是要做兼容处理
调用wx.getLocalImgData,遍历提供localId 内元素给他,能够获取BASE64的图片数据。注意这里是异步执行
else{
最通用情况,正常的代码即可
}
)
实际完美运行代码如下,也是参考网上部分的代码,并做了修复,显得比较复杂。其实理解了上面说的思路,可以完全不用参考我的实际代码。按自己的方式写就行了。另外建议复制代码到自己的IDE或者编辑器下查看,时间和精力关系,我没有做主题的代码显示优化,相信你能找到我的博客,也不会是一般人,这点小问题困扰不了你,如果有疑问或者需要帮助,可以给我留言,我看到后会尽快回复。
var images={ localId:[], serverId:[], } ioslocId=[];//用于兼容ios的本地id列表 图片是base64格式的 a=0; // 初始化变量的方式 wx.ready(function(){ var total=9;/*限制上传的数量*/ var sum=0;/*每次上传的数量*/ var upsum=0;/*已上传的总数*/ choose.onclick=function(){ wx.chooseImage({ count:9,/*默认为9*/ success:function(res){ images.localId=res.localIds;/*保存到images*/ sum=images.localId.length; if((upsum+sum)>total){ var last=total-upsum; return false; } if (window.__wxjs_is_wkwebview) { //判断ios是不是用的 wkwebview 内核 for(var i=0;i<images.localId.length;i++){ wx.getLocalImgData({ //循环调用 getLocalImgData localId:res.localIds[i], // 图片的localID success: function (res) { var localData = res.localData; // localData是图片的base64数据,可以用img标签显示 localData = localData.replace('jgp', 'jpeg');//iOS 系统里面得到的数据,类型为 image/jgp,因此需要替换一下 ioslocId.push(localData); //把base64格式的图片添加到ioslocId数组里 这样该数组里的元素都是base64格式的 if (a == 0) { $("#ImgPr").attr('src', localData); $(".imageitem").css("background-image", "url(" + localData + ")"); a = 1 } else { $new = $(".imageitem").last().clone(true); $new.find('img').attr('src', localData); $new.css("background-image", "url(" + localData + ")"); $new.insertAfter($(".imageitem").last()); } },fail:function(res){ alert("res"); } }); } }else{ //如果不是用的wkwebview 内核 或者是用的安卓系统 执行下面的xunh /*相应位置预览*/ var count=res.localIds.length+upsum; for(j=upsum;j<count;j++){ if(j==0){ $("#ImgPr").attr('src',res.localIds[0]); $(".imageitem").css("background-image","url("+res.localIds[0]+")"); }else{ $new=$(".imageitem").last().clone(true); $new.find('img').attr('src',res.localIds[j-upsum]); $new.css("background-image","url("+res.localIds[j-upsum]+")"); $new.insertAfter($(".imageitem").last()); } } } upsum=upsum+sum; /*上传图片到微信服务器*/ var i=0;len=images.localId.length; wxupload(); function wxupload(){ wx.uploadImage({ localId: images.localId[i], // 需要上传的图片的本地ID,由chooseImage接口获得 success: function (res) { i++; images.serverId.push(res.serverId); //将上传成功后的serverId保存到serverid if(i < len){ wxupload(); } } }); } } } ); } });
Comments | NOTHING