一. 缓存原理
图片缓存原理原理是,如内存没图片,去磁盘找,若磁盘也没有,则根据url去下载,然后缓存到内存和磁盘中,简单易用
缓存的目录结构如下图:
varljFilePath:String =NSHomeDirectory() +"/Documents/"+"LJImageCache/"
为了确保缓存下来的图片的唯一性,所以此处采用图片的url+md5=唯一标识符,来存储图片,如上图图片的名称。
创建一个Sting+MD5.swift字符串分类文件(同时此处需要创建一个bridge.h桥接文件,引入这个头文件
#import <CommonCrypto/CommonDigest.h>,md5加密方法需要使用的文件)
1.bridge.h桥接文件如下:
2. Sting+MD5.swift文件如下
- #ifndef bridge_h
- #define bridge_h
- #import <CommonCrypto/CommonDigest.h>
- #endif /* bridge_h */
- 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.图片读取
3. 读写磁盘文件
- 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)
- }
- }
- }
(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
- }
- }
- }