gysidon
gysidon
  • 发布:2018-11-16 14:03
  • 更新:2019-06-13 13:20
  • 阅读:1617

【报Bug】本地缓存的图片IOS真机无法显示,模拟器正常

分类:uni-app

详细问题描述(DCloud产品不会有明显的bug,所以你遇到的问题大都是在特定环境下才能重现的问题,请仔细描述你的环境和重现方式,否则DCloud很难排查解决你的问题)
[内容]

/**  
 * 图片本地缓存  
 */  
Vue.prototype.getImg = async function(url) {  
    if (url == undefined || url.length < 5 | url.substr(0, 4) != 'http') {  
        return url;  
    }  
    //获取下载文件地址  
    let downurl = url;  
    var start = url.lastIndexOf(".");  
    var end = url.lastIndexOf("?") >= 0 ? url.lastIndexOf('?') : url.length;  
    var ext = url.substring(start, end);  
    var ext_num = url.indexOf(ext);  
    if(ext_num>=0){  
        downurl = url.substr(0,ext_num)+ext;  
    }  

    //读取缓存文件  
    let CacheImage = uni.getStorageSync("CacheImage");  
    let Ids = CacheImage.Ids;  
    let Val = CacheImage.Val;  
    let MName = utils.md5(downurl);  
    if(typeof CacheImage=='object' && typeof Ids=='object' && typeof Val=='object'){  
        //有缓存  
        let index = Ids.indexOf(MName);  
        if(index>=0){  
            return Val[index];  
        }  
    }else{  
        Ids = [];  
        Val = [];  
        CacheImage = {Ids:Ids,Val:Val}  
    }  
    async function getImgs(){  
        return new Promise(function(resole){  
            uni.downloadFile({  
                url:downurl,  
                success:function(res){  
                    if(res.statusCode===200){  
                        uni.saveFile({  
                            tempFilePath:res.tempFilePath,  
                            success:function(e){  
                                Ids.push(MName);  
                                Val.push(e.savedFilePath);  
                                CacheImage = {Ids:Ids,Val:Val}  
                                uni.setStorageSync("CacheImage",CacheImage);  
                                resole(e.savedFilePath)  
                            },  
                            fail:function(){  
                                resole(res.tempFilePath)  
                            }  
                        })  
                    }else{  
                        resole(url);  
                    }  
                },fail:function(){  
                    resole(url);  
                }  
            })  
        })  
    }  

    return await getImgs();  
}

重现步骤
[步骤]
开始是用的5+接口,也出现了这种情况,后面改成uni的接口写了这个方法来处理本地图片缓存,但是在真机上还是无法显示图片,模拟器正常。
本地打包,线上打包没试过,太慢了。
[结果]
解决这个问题
[期望]
[如果语言难以表述清晰,可以拍一个视频或截图,有图有真相]

IDE运行环境说明
[HBuilder 或 HBuilderX]
HBuilderX
[IDE版本号]
1.1.0.20181030
[windows版本号]
[mac版本号]
10.13.6

App运行环境说明
[Android版本号]
[iOS版本号]
12.0.1
[手机型号]
iphone 6
[模拟器型号]
iphone 6 IOS 11.0.1

附件
[IDE问题请提供HBuilderX运行日志。菜单帮助-查看运行日志,点右键打开文件所在目录,将log文件压缩成zip包上传]
[App问题请提供可重现问题的代码片段,你补充的细一点,问题就解决的快一点]
[安装包]

联系方式
[QQ]

2018-11-16 14:03 负责人:无 分享
已邀请:
gysidon

gysidon (作者)

没人回答我吗???都没人遇到这问题吗?

  • 灰色的灵魂

    您这个问题解决了么,求代码。我也在做本地缓存。

    2019-06-13 12:35

  • gysidon (作者)

    回复 灰色的灵魂: 第一次加载网络图片,第二次以后加载本地缓存图片就行了;

    2019-06-13 12:39

  • 灰色的灵魂

    回复 gysidon: 您好,我全局定义您提供的代码,可以保存到本地了。然后用了Promise.then封装保存了数据,但是发现存储到的是_doc/uniapp_save/1560400449418.jpg这样的位置,然后却不显示。能提供下您这个页面的代码嘛,27888677@qq.com 衷心感谢。

    2019-06-13 13:13

gysidon

gysidon (作者)

我这边代码重新写过了


/**  
 * 图片本地缓存  
 */  
Vue.prototype.getImg = function(url) {  
    if (url == undefined || url.length < 5 | url.substr(0, 4) != 'http') {  
        return url;  
    }  
    // #ifdef APP-PLUS  
    //获取下载文件地址  
    let downurl = url;  
    var start = url.lastIndexOf(".");  
    var end = url.lastIndexOf("?") >= 0 ? url.lastIndexOf('?') : url.length;  
    var ext = url.substring(start, end);  
    var ext_num = url.indexOf(ext);  
    if (ext_num >= 0) {  
        downurl = url.substr(0, ext_num) + ext;  
    }  

    //读取缓存文件   
    let MName = utils.md5(downurl);  
    //检查是否存在文件后缀名  
    let names = ['jpg','jpeg','png','gif'];  
    if(names.indexOf(ext)<=0){  
        downurl = url;  
    }  
    let cacheUrl = plus.storage.getItem(MName);  
    //缓存文件存在,直接读  
    if(cacheUrl!=null){  
        return cacheUrl;  
    }  
    utils.downStart(downurl,MName,ext);  
    //#endif  

    return url;  
}  

/**  
 * 创建下载任务  
 */  
function downStart(downurl, name, ext) {  
    //检查是否存在文件后缀名  
    let names = ['jpg','jpeg','png','gif'];  
    if(names.indexOf(ext)<=0){  
        var filename = (name + '.png').replace('..', '.');  
    }else{  
        var filename = (name + '.' + ext).replace('..', '.');  
    }  
    var dtask = plus.downloader.createDownload(downurl, {  
        'filename': '_doc/cachefile/' + filename  
    }, function(d, status) {  
        // 下载完成  
        if (status == 200) {  
            //删除原来的文件  
            console.log('图片缓存完成:'+d.filename)  
            plus.storage.setItem(name, d.filename);  
        }else{  
            console.log("下载失败:"+status+",文件地址:"+downurl)  
        }  
    },function(e){  
        console.log(JSON.stringify(e))  
    });  
    dtask.start();  
}
  • 灰色的灵魂

    非常感谢。衷心感谢。

    2019-06-13 13:22

  • 灰色的灵魂

    搞定了,功能实现了,谢谢,

    2019-06-13 13:55

  • 灰色的灵魂

    大佬,碰到个问题,请问下您是怎么解决的呢,比如我现在一个首页调用了几次这个方法,但是存在相同的图片,所以首次加载的时候,一张图片,可能下载几次。取的最后一次的缓存,这个问题您怎么处理的呢,是模拟排队嚒?

    2019-06-13 14:15

  • 5***@qq.com

    回复 灰色的灵魂: 你解决了吗?

    2019-11-05 09:19

该问题目前已经被锁定, 无法添加新回复