美文网首页
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