美文网首页
100行代码简单封装图片缓存

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

作者: 晚雪浓情 | 来源:发表于2017-01-06 16:32 被阅读35次

虽然这个功能都被写烂了,但反正有空,动手用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请求图片并执行回调
  • 如果需要磁盘缓存,先判断有没有缓存文件,第一次肯定没有,就需要去下载并缓存;
    如果有缓存文件,就尝试读一下缓存,没有此图片的缓存或文件读取失败 还是要去下载并缓存。

相关文章

网友评论

      本文标题:100行代码简单封装图片缓存

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