100行代码简单封装图片缓存

虽然这个功能都被写烂了,但反正有空,动手用Swift3.0稍微封装了一下,100行不到搞定,简单粗暴直接上代码。

func getImage(with urlString:String,isDiskCache:Bool = false,timeout:TimeInterval = 10)
    {
        let path = NSSearchPathForDirectoriesInDomains(.cachesDirectory,.allDomainsMask, true)[0] + "/image.txt"
        
        let finish = { image in
            DispatchQueue.main.async{
                self.movieImg.image = image
            }
        }
        
        let handle = {
        
            if let url = URL(string: urlString)
            {
                URLSession.shared.downloadTask(with: URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: timeout)){
                    location,response,error in
                    
                    if let fileUrl = location
                    {
                        do
                        {
                            let data = try Data(contentsOf: fileUrl)

                            //需要磁盘缓存
                            if isDiskCache
                            {
                                var dict = [String:Data]()
                                
                                
                                //先取一下取得出来就接着存
                                if let fileData = FileManager.default.contents(atPath: path)
                                {
                                    let unarchiver = NSKeyedUnarchiver(forReadingWith: fileData)
                                    
                                    if let temp = unarchiver.decodeObject(forKey: "imgData") as? [String:Data]
                                    {
                                        dict = temp
                                    }
                                }
                                
                                //合并数据
                                dict["\(url)"] = data
                                
                                //编码
                                let fileData = NSMutableData()
                                let archiver = NSKeyedArchiver(forWritingWith: fileData)
                                archiver.encode(dict, forKey: "imgData")
                                archiver.finishEncoding()
                                
                                //覆盖写入
                                if !fileData.write(to:URL(fileURLWithPath: path, isDirectory: false), atomically: true)
                                {
                                    print("保存失败")
                                }
                            }
                            
                            finish(UIImage(data:data))
                        }
                        catch
                        {
                            print(error)
                        }
                    }
                    
                }.resume()
            }
        }
        
        
        //磁盘缓存
        if isDiskCache
        {
            DispatchQueue.global().async{
                
                //文件磁盘缓存路径下能取出来
                if let fileData = FileManager.default.contents(atPath: path)
                {
                    let unarchiver = NSKeyedUnarchiver(forReadingWith: fileData)
                    if let dict = unarchiver.decodeObject(forKey: "imgData") as? [String:Data],let data = dict["\(urlString)"]
                    {
                        finish(UIImage(data:data))
                    }
                    //1.文件坏了 2.没有这个图片的缓存 3.根本取不出来 --->乖乖下载
                    else
                    {
                        handle()
                    }
                    unarchiver.finishDecoding()
                }
                else
                {
                    handle()
                }
            }
        }
        //内存缓存
        else
        {
            //内存缓存会容易被删除
            handle()
        }
    }

简单解释一下

  • handle闭包简单封装了一下涉及网络请求的部分。finish闭包简单封装了一下回调部分,可以改写这个闭包轻松改变回调内容。
  1. 如果需要磁盘缓存,isDiskCache设置为true。(默认为false)
  2. 默认超时为10s

函数流程:

  1. 如果非磁盘缓存,则直接去handle,根据URL请求图片并执行回调
  • 如果需要磁盘缓存,先判断有没有缓存文件,第一次肯定没有,就需要去下载并缓存;
    如果有缓存文件,就尝试读一下缓存,没有此图片的缓存或文件读取失败 还是要去下载并缓存。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,862评论 25 708
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,841评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,192评论 4 61
  • 我是80后一个孩子的妈妈。每次陪着孩子坐在沙发上一起观看生动有趣的动画片时不禁总会想起自己小时候看的动画片...
    诗一闲修阅读 940评论 9 3
  • 早上失误导致签到发生小状况,连累整个签到成绩,对不起大家。这几天脑子有些浆糊了,事情一多就晕头转向,合理规划时间还...
    4017b3bae81c阅读 187评论 0 0