swift3.0 简单的网络图片缓存原理

前端之家收集整理的这篇文章主要介绍了swift3.0 简单的网络图片缓存原理前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一. 缓存原理

图片缓存原理原理是,如内存没图片,去磁盘找,若磁盘也没有,则根据url去下载,然后缓存到内存和磁盘中,简单易用

缓存的目录结构如下图:

//存储图片文件

varljFilePath:String =NSHomeDirectory() +"/Documents/"+"LJImageCache/"


二. 图片名称处理

为了确保缓存下来的图片的唯一性,所以此处采用图片的url+md5=唯一标识符,来存储图片,如上图图片名称

创建一个Sting+MD5.swift字符串分类文件(同时此处需要创建一个bridge.h桥接文件,引入这个头文件

#import <CommonCrypto/CommonDigest.h>,md5加密方法需要使用的文件

1.bridge.h桥接文件如下:

#ifndef bridge_h
#define bridge_h

#import <CommonCrypto/CommonDigest.h>

#endif /* bridge_h */
2. Sting+MD5.swift文件如下

import Foundation

extension String {
    var md5 : String{
        let str = self.cString(using: String.Encoding.utf8)
        let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        
        CC_MD5(str!,strLen,result)
        
        let hash = NSMutableString()
        for i in 0 ..< digestLen {
            hash.appendFormat("%02x",result[i])
        }
        result.deinitialize()
        
        return String(format: hash as String)
    }
}

三.图片缓存和读取

1. 图片缓存

func urlSession(_ session: URLSession,task: URLSessionTask,didCompleteWithError error: Error?)
    {
        if ljcallBackClosure != nil,let data = self.responseData{
            weak var weakSelf : LJOpreationManager? = self
            DispatchQueue.main.async
            {
                print("URLSessionDataDelegate----数据下载完毕")
                
                LJCacheDataManage.shared.setMemoryCache((task.currentRequest?.url?.absoluteString)!,data as Data)
               
               //图片缓存,根据唯一的url来作为存储数据的名称
               let a =  LJFileManager.shared.writeFile((task.currentRequest?.url?.absoluteString)!,data as NSData)
                
                print("-----写入文件成功\(a)")
                
                //将接收的数据结果回调到前台,用于进度展示
                weakSelf?.ljcallBackClosure!(data as Data,nil)
            }
        }
    }

2.图片读取

 public func retrieveImage(_ ljurl: String,_ ljcallback: @escaping OpreationClosure){
        
        if ljurl != "" {
            
            if LJFileManager.shared.readFileFromCache(ljurl) != nil {
                //将接收的数据结果回调到前台,用于进度展示
                print("获取的是Disk缓存数据哦完毕")
                ljcallback(LJFileManager.shared.readFileFromCache(ljurl) as! Data,nil)
            }
            //首先取缓存数据,没取到的话,直接下载
           else if LJCacheDataManage.shared.getMemoryCache(ljurl) != nil {
                //将接收的数据结果回调到前台,用于进度展示
                print("获取的是Memory缓存数据哦完毕")
                ljcallback(LJCacheDataManage.shared.getMemoryCache(ljurl),nil)
            }
            else
            {
               _  = self.requestWebByUrl(ljurl,ljcallback)
            }
        }
    }
3. 读写磁盘文件

(1)存储的时候给url进行md5加密得到fileName.md5文件名称,然后存储,如上面的截图

(2)读取文件时,给url进行md5加密得到path.md5的,然后获取文件数据

    /* 写文件
       fileName: 文件名称
       data: 数据data
    */
    func writeFile(_ fileName:String,_ data:NSData) -> Bool{
        
        //let filePath:String = NSHomeDirectory() + "/Documents/" + fileName.md5
        //return  data.write(toFile: filePath,atomically: true)
        guard self.isExistFileDir(ljFilePath) else{
           return false
        }
        
        guard let filePath : String = ljFilePath + fileName.md5 else{
            return false
        }
        return data.write(toFile: filePath,atomically: true)
    }
    
    //读取文件 -(根据路径)
    func readFileFromCache(_ path:String) -> NSData?{
        
        if self.isExistFileDir(ljFilePath)
        {
            let ljpatch = ljFilePath + path.md5
            var result:NSData?
            do{
                result = try NSData(contentsOfFile: ljpatch,options: Data.ReadingOptions.uncached)
            }catch{
                return nil
            }
            return result
        }
        return nil
    }


4.读写内存文件

import Foundation

class LJCacheDataManage: NSObject{
    
    //单例
    public static let shared = LJCacheDataManage()
    
   // public var diskCache =
    
    //缓存的数据
    public var memoryCache = Dictionary<String,Data>()
    
    //返回缓存的数据
    func getMemoryCache(_ urlStr : String) ->  Data? {
        
        print("返回缓存的数据------\(memoryCache[urlStr] ?? nil)")
        return (memoryCache[urlStr] ?? nil)
    }
    
    //设置缓存值
    func setMemoryCache(_ urlStr : String,_ data : Data){
        if urlStr != "",data != nil {
            memoryCache[urlStr] = data
        }
    }
}
原文链接:https://www.f2er.com/swift/321420.html

猜你在找的Swift相关文章