美文网首页
SDWebImage与阿里云OSS Bucket Private

SDWebImage与阿里云OSS Bucket Private

作者: younger_times | 来源:发表于2024-05-06 14:50 被阅读0次

    实现自定义路径缓存

    let image = SDImageCache(namespace:items[indexPath.row].id.description.MD5(), diskCacheDirectory: DocumentPath! + "/MD_img/preview/") //将ID MD5后,作为文件夹名,存放于 Document/MD_img/preview下
    let manager = SDWebImageManager(cache: image, loader: loader)
    
    //获取缓存,如果存在读取缓存
    if let localImg = image.imageFromDiskCache(forKey: url.absoluteString){
                    cell.img.image = localImg
    }else{
    //不存在缓存,下载
                    manager.loadImage(with: url, progress: nil) {img, _, _, _, _, _ in
                                    cell.img.image = img
                    }
    }
    

    SDWebImage与OSS的安全策略

    为了避免额外的流量费用,避免图片等资源流入外网;OSS的策略中,Private只有授权才能访问。大多数为了图方便选择Public

    如果将选择Private,就需要以下的配置:

    定义了一个Config

    根据项目实际情况,进行自操作。

    class OSSUploader: NSObject {
                    struct Config {
                                    static var oss_domain = ""
                                    static var accessKeyId = ""
                                    static var accessKeySecret = ""
                                    static var bucketName = ""
                                    static var endpoint = ""
                                    static let expirationInterval:TimeInterval = 3600 //图片过期时间:私有访问【Bucket ACL】 时间:【秒】
        }
    }
    

    扩展两个分类

    它的作用在于,帮你完成访问图片时,拼接后面权限的参数

    public extension String{
        ///在URL中包含签名【读写权限:私有】
        var OSSSafeUrl:String{
                        let url = Foundation.URL(string: self)
                        if let objectKey = url?.relativePath.jq_substring(from: 1){
                                        let response = OBSUploader.shared.ossClient.presignConstrainURL(withBucketName: OBSUploader.Config.bucketName, withObjectKey: objectKey, withExpirationInterval: OBSUploader.Config.expirationInterval)
                                        if response.isSuccessful(){
                                                        guard let urlsafe = response.result as? String else { return self }
                                                        return urlsafe
                                        }
                        }
                        return self
        }
    }
    
    public extension URL{
        ///在URL中包含签名 【读写权限:私有】
        var OSS_SafeUrl:URL{
                        let objectKey = self.relativePath.jq_substring(from: 1)
                        let response = OBSUploader.shared.ossClient.presignConstrainURL(withBucketName: OBSUploader.Config.bucketName, withObjectKey: objectKey, withExpirationInterval: OBSUploader.Config.expirationInterval)
                        if response.isSuccessful(){
                                        guard let urlsafe = response.result as? String else { return self }
                                        return URL(string:urlsafe) ?? self
                        }
                        return self
        }
    }
    

    引发的问题

    以上就已经实现了对Private的资源读取,但会发现一个问题,每一次请求都是以新链接请求,那么SDWebImage都会认为是新链接,会重新进行一次下载,就造成了缓存的图片URL,相同资源会多次缓存。刷新List时,明显出现闪动。这并不是我们想要的缓存效果。

    原因:SDWebImage缓存的原理在将URL进行MD5为图片名称,OSS的Private后,参数都不一样,MD5后都会不同。

    可以通过以下方法解决:
    manager实现cacheKeyFilter,对URL后面部分参数截取,将前面的链接作为需要MD5的KEY。

    manager.cacheKeyFilter = SDWebImageCacheKeyFilter(block: { url in
            let img = url.absoluteString.components(separatedBy: "?").first
            return img
    })
    

    将下载图片的改为OSS_SafeUrl

        manager.loadImage(with: url.OSS_SafeUrl, progress: nil) {img, _, _, _, _, _ in
        cell.img.image = img
        }
    

    通过模拟器打印路径发现,即使采用了Private策略,图片依然是只有一张,保护了APP内,被抓包流入公网的可能。也同时实现了图片缓存的能力。

    相关文章

      网友评论

          本文标题:SDWebImage与阿里云OSS Bucket Private

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