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

一. 缓存原理

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

缓存的目录结构如下图:

 //存储图片的文件夹

 var ljFilePath: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
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值