• 图片缓存原理原理是,如内存没图片,去磁盘找,若磁盘也没有,则根据url去下载,然后缓存到内存和磁盘中,简单易用 缓存的目录结构如下图:  //存储图片的文件夹  var  ljFilePath:String = NSHomeDirectory() +...

    一. 缓存原理

    图片缓存原理原理是,如内存没图片,去磁盘找,若磁盘也没有,则根据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
            }
        }
    }
    



    展开全文
  • iOS开发之swift版异步加载网络图片  与SDWebImage异步加载网络图片的功能相似,只是代码比较简单,功能没有SD的完善与强大,支持缺省添加图片,支持本地缓存。  异步加载图片的核心代码如下:  func ...

    iOS开发之swift版异步加载网络图片

        与SDWebImage异步加载网络图片的功能相似,只是代码比较简单,功能没有SD的完善与强大,支持缺省添加图片,支持本地缓存。

         异步加载图片的核心代码如下:

     func setZYHWebImage(url:NSString?, defaultImage:NSString?, isCache:Bool){
            var ZYHImage:UIImage?
            if url == nil {
                return
            }
            //设置默认图片
            if defaultImage != nil {
                self.image=UIImage(named: defaultImage!)
            }
            //是否进行缓存处理
            if isCache {
            //缓存管理类
                var data:NSData?=ZYHWebImageChcheCenter.readCacheFromUrl(url!)
                if data != nil {
                    ZYHImage=UIImage(data: data!)
                    self.image=ZYHImage
                }else{
                //获取异步线程
                   var dispath=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
                    dispatch_async(dispath, { () -> Void in
                        var URL:NSURL = NSURL(string: url!)!
                        var data:NSData?=NSData(contentsOfURL: URL)
                        if data != nil {
                            ZYHImage=UIImage(data: data!)
                            //写缓存
                            ZYHWebImageChcheCenter.writeCacheToUrl(url!, data: data!)
                            //主线程中刷新UI
                            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                                //刷新主UI
                                self.image=ZYHImage
                            })
                        }
                        
                    })
                }
            }else{
                var dispath=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
                dispatch_async(dispath, { () -> Void in
                    var URL:NSURL = NSURL(string: url!)!
                    var data:NSData?=NSData(contentsOfURL: URL)
                    if data != nil {
                        ZYHImage=UIImage(data: data!)
                        //写缓存
                        dispatch_async(dispatch_get_main_queue(), { () -> Void in
                            //刷新主UI
                            self.image=ZYHImage
                        })
                    }
                    
                })
            }
        }
        
    }

    缓存的处理这里采用的是写文件的方式,通过文件名来对缓存进行管理,这个框架还不完善,后面会加入缓存清除等功能。缓存的核心代码如下:

    class func readCacheFromUrl(url:NSString)->NSData?{
            var data:NSData?
            var path:NSString=ZYHWebImageChcheCenter.getFullCachePathFromUrl(url)
            if NSFileManager.defaultManager().fileExistsAtPath(path) {
                data=NSData.dataWithContentsOfMappedFile(path) asNSData
            }
            return data
        }
        
        class func writeCacheToUrl(url:NSStringdata:NSData){
            var path:NSString=ZYHWebImageChcheCenter.getFullCachePathFromUrl(url)
           println(data.writeToFile(path, atomically: true))
        }
        //设置缓存路径
        class func getFullCachePathFromUrl(url:NSString)->NSString{
            var chchePath=NSHomeDirectory().stringByAppendingString("/Library/Caches/MyCache")
            var fileManager:NSFileManager=NSFileManager.defaultManager()
            fileManager.fileExistsAtPath(chchePath)
            if !(fileManager.fileExistsAtPath(chchePath)) {
                fileManager.createDirectoryAtPath(chchePath, withIntermediateDirectories: true, attributes: nil, error: nil)
            }
            //进行字符串处理
            var newURL:NSString
            newURL=ZYHWebImageChcheCenter.stringToZYHString(url)
            chchePath=chchePath.stringByAppendingFormat("/%@", newURL)
            return chchePath
        }
        
        class func stringToZYHString(str:NSString)->NSString{
            var newStr:NSMutableString=NSMutableString()
            for var i:NSInteger=0; i < str.length; i++ {
                var c:unichar=str.characterAtIndex(i)
                if (c>=48&&c<=57)||(c>=65&&c<=90)||(c>=97&&c<=122){
                    newStr.appendFormat("%c"c)
                }
            }
            return newStr.copy() as NSString
            
        }

    框架的github地址,欢迎指正与扩展:https://github.com/ZYHshao/swift-ZYHWebImage

    因xcode的版本不同,swift语言语法随环境时常会变化,此版本在6.1中可用,更高版本中需要修改少部分即可。

    展开全文
  • /* 网络请求数据的缓存策略  */ /* 简单缓存思想1  ->有网络情形:从网络中更新数据且进行缓存;  ->无网络情形:直接从缓存中取出;  */ /* 简单缓存思想2 (1...
    /*  网络请求数据的缓存策略




     */






    /* 简单缓存思想1 


    ->有网络情形:从网络中更新数据且进行缓存; 
    ->无网络情形:直接从缓存中取出; 
    */








    /* 简单缓存思想2


    (1) 什么是“Last-Modified”?   请求资源文件的最后修改时间

       在浏览器第一次请求某个url时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务器
    端最后被修改的时间;  格式类似于 Last-Modifed: Fri, 12 May 2006 18:53:33 GMT 
      
      客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会想服务器传送 IF-Modified-Since报头,询问该时间之后文件是否被修改过; 
    if-Modified-Since:Fri, 12 May 2006 18:53:33 GMT 


    如果服务器端的资源没有变化,则自动返回HTTP304(not changed)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启
    服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。




     请求时的字段:  Last-Modified
     响应时的字段:  If-Modified-Since






    (2) 什么是"Etag"?


       HTTP协议规定说明定义ETag为"被请求变量的实体值". 另一种说法是,ETag是一个可以与Web资源关联的记号(token).服务器单独负责判断记号是
     什么及其含义,并在http响应头中将其传送到客户端,以下是服务器端返回的格式: ETag: "50b1c1d4f775c61:df3" ;


     客户端的查询更新格式是这样的:  If-None-Match: W/"50b1c1d4f775c61:df3" 
     如果ETag没改变,则返回状态304且不返回其他数据;




      请求时的字段: ETag
      响应时的字段: If-None-Match






    (3) 那么Last-Modified 和 ETags如何帮助提高性能?

       把Last-Modified 和 ETags请求的http报头一起使用,这样可利用客户端嘚缓存。因为服务器首先产生Last-Modified/ETags标记,服务器稍后使用它
    来判断页面是否已经被修改。本质上,客服端通过将该记号传回服务器,要求服务器验证其客服端的缓存;


    过程:  
     (1) 客户端请求一个页面(A)
     (2) 服务器返回页面A, 并在给A家上一个 Last-Midified/ETag
     (3) 客服端展现该页面, 并将页面连同Last-Modified/ETag一起缓存
     (4) 客户再次请求页面A, 并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
     (5) 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回状态码304以及空的响应体;






    两种思想结合:

    1. 没有网络的情形,只浏览本地的缓存;
    2. 有网络时,校对Last-Modified 或者 ETag, 如果一致,表示没有修改,那么使用缓存;
      有网络时,不过不一致,那么服务器下发新数据;












    上述是将的缓存使用策略
    下面该讲述 缓存命中机制  以及命中概率, 依旧缓存清除机制(缓存总会满,所以需要按某个机制进行缓存的清除)










    缓存机制:
    用来改善应用所表现出的性能。
       (1) 提供离线使用功能
    (2) 优化应用,用容量换取时间(比如内存中存储图片,存储访问的数据,减少用户流量)


     */

    展开全文
  • swift3.0加载网络图片

    iOS加载本地图片很简单,只需要将图片当做资源加入到工程,imageView.image = UIImage(named: "这里加入导入的资源名字")就可以了,然而对于看图app,不可能将海量的图片都加入到app当中,而是通过网络获取图片,然后再用来显示,这样做就能实时从网络上获取最新的图片。废话不多说,现在讲讲再swfit3.0中用到的几种加载网络图片的方法。


    // storyboard拉一个imageView,关联输出口
    @IBOutlet weak var loadImageFromURL: UIImageView!

    方法一:同步加载网络图片

            // 方法一: 同步加载网络图片
            let url = URL(string: "http://i.imgur.com/w5rkSIj.jpg")
            // 从url上获取内容
            // 获取内容结束才进行下一步
            let data = try? Data(contentsOf: url!)
            
            if let imageData = data {
                let image = UIImage(data: data!)
                loadImageFromURL.image = image
            }
    

    方法二:异步加载网络图片

    // 方法二: 异步加载网络图片
            let urlString = "http://i.imgur.com/w5rkSIj.jpg"
            let catPictureURL = URL(string: urlString)!
            
            // url带中文的,urlString必须经过处理,加addingPercentEncoding,不然catPictureURL为nil,不带中文就不需要
            // 这个是url带中文的处理方法
            //        let urlString = "http://localhost:8080/AlbumImage/杀破狼.jpg"
            //        let unsafeP = urlString.addingPercentEncoding(withAllowedCharacters: NSCharacterSet(charactersIn:"`#%^{}\"[]|\\<> ").inverted)!
            //        let catPictureURL = URL(string: unsafeP)!
            
            
            // 用默认配置创建一个session对象
            let session = URLSession(configuration: .default)
            
            // 定义一个下载task,下载task会把url的内容读到data中,然后你可以用data来操作,如加载图片,缓存图片等
            let downloadPicTask = session.dataTask(with: catPictureURL) { (data, response, error) in
                // The download has finished.
                if let e = error {
                    print("Error downloading cat picture: \(e)")
                } else {
                    // No errors found.
                    // It would be weird if we didn't have a response, so check for that too.
                    if let res = response as? HTTPURLResponse {
                        print("Downloaded cat picture with response code \(res.statusCode)")
                        if let imageData = data {
                            // Finally convert that Data into an image and do what you wish with it.
                            let image = UIImage(data: imageData)
                            // Do something with your image.
                            DispatchQueue.main.async {
                                self.loadImageFromURL.image = image
                            }
                            
                        } else {
                            print("Couldn't get image: Image is nil")
                        }
                    } else {
                        print("Couldn't get response code for some reason")
                    }
                }
            }
            
            // 这一句必须要加,不然task不会开始
            downloadPicTask.resume()


    
    

    方法三:异步加载网络图片

    //方法三: 异步加载网络图片
            //创建URL对象
            let url = URL(string:"http://i.imgur.com/w5rkSIj.jpg")!
            //创建请求对象
            let request = URLRequest(url: url)
            
            let session = URLSession.shared
            let dataTask = session.dataTask(with: request, completionHandler: {
                (data, response, error) -> Void in
                if error != nil{
                    print(error.debugDescription)
                }else{
                    //将图片数据赋予UIImage
                    let img = UIImage(data:data!)
                    
                    // 这里需要改UI,需要回到主线程
    //                DispatchQueue.main.async {
                        self.loadImageFromURL.image = img
    //                }
    
                }
            }) as URLSessionTask
            
            //使用resume方法启动任务
            dataTask.resume()

    以上三个方法在swift3.0可以使用,这里用到http,所以在运行之前先设置一下Info.plist,在Info.plist中添加“App Transport Security Settings”,然后在“App Transport Security Settings”中将Allow Arbitrary Loads设置为YES(如图1),然后在运行,要不然运行时看不到任何效果的。
    图1

    最后将加载网络图片做个简单封装,扩展UIImageView:

    extension UIImageView {
        func downloadedFrom(url: URL, contentMode mode: UIViewContentMode = .scaleToFill) {
            contentMode = mode
            URLSession.shared.dataTask(with: url) { (data, response, error) in
                // The download has finished.
                if let e = error {
                    print("Error downloading cat picture: \(e)")
                } else {
                    // No errors found.
                    // It would be weird if we didn't have a response, so check for that too.
                    if let res = response as? HTTPURLResponse {
                        print("Downloaded cat picture with response code \(res.statusCode)")
                        if let imageData = data {
                            // Finally convert that Data into an image and do what you wish with it.
                            let image = UIImage(data: imageData)
                            // Do something with your image.
                            DispatchQueue.main.async() { () -> Void in
                                self.image = image
                            }
    
                        } else {
                            print("Couldn't get image: Image is nil")
                        }
                    } else {
                        print("Couldn't get response code for some reason")
                    }
                }
                
            }.resume()
            
        }
        func downloadedFrom(link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
            guard let url = URL(string: link) else { return }
            downloadedFrom(url: url, contentMode: mode)
        }
    }

    调用:

    let urlString = "http://i.imgur.com/w5rkSIj.jpg"
            if let url = URL(string: urlString) {
                loadImageFromURL.downloadedFrom(url: url)
            }




    展开全文
  • 参考:https://www.jianshu.com/p/55bbfbdf78de =============方法一:使用sdwebImage ... 在桥接文件中导入 #import &lt;SDWebImage/UIImageView+WebCache.h&... let imagev:UIImageV...

    参考:https://www.jianshu.com/p/55bbfbdf78de

    =============方法一:使用sdwebImage

    下载地址:https://github.com/rs/SDWebImage

    在桥接文件中导入

    #import <SDWebImage/UIImageView+WebCache.h>

    使用:

      let imagev:UIImageView=UIImageView.init(frame:CGRect(x:0,y:0,width:100,height:100))

            view .addSubview(imagev)

     

         imagev.sd_setImage(with: NSURL.init(string: "http://test.ahwofu.com/public/upload/ad/2018/01-13/abc1cc5d2e661e4a")! as URL, placeholderImage: UIImage.init(named: "bannerhomeOne"), options: [], progress: nil, completed:nil)

     

    ==============方法二:Kingfisher

    下载地址:https://github.com/onevcat/Kingfisher

     

    • 图片缓存ImageCache 使用
         ImageChache 给你提供了多级缓存,可以使用内存、磁盘存储,还提供了存储、检索、清除图片、移除等操作,如果你需要监听到磁盘的变化可以通过KingfisherDidCleanDiskCacheNotification添加通知。
    •  

     

    // ImageCache,默认是

    let cache = ImageCache.default

    // 设置内存缓存的大小,默认是0 pixel表示no limit ,注意它是像素为单位,与我们平时的bytes不同

    cache.maxMemoryCost =10 * 1024 * 1024

    // 磁盘缓存大小,默认0 bytes表示no limit (50 * 1024)

    cache.maxDiskCacheSize =50 * 1024 * 1024

    // 设置缓存周期 (默认1 week)

    cache.maxCachePeriodInSecond =60 * 60 * 24 *7

    // 存储一张图片, Key 可用于后期检索资源、删除以及在删除时的一个通知参数

    cache.store(UIImage(named:"test")!, forKey: "test")

    // 删除

    cache.removeImage(forKey:"test")

    // 检索图片

    let imgDisk = cache.retrieveImageInDiskCache(forKey:"test")

    let imgMemo = cache.retrieveImageInMemoryCache(forKey:"test")

    // 异步检索

    cache.retrieveImage(forKey:"test", options: nil) { (_,_) in

        

    }

    // 清除

    cache.clearDiskCache()

    cache.clearMemoryCache()

    cache.clearDiskCache {

        

    }

    // 清除过期缓存

    cache.cleanExpiredDiskCache()

    cache.cleanExpiredDiskCache {

        

    }

    cache.backgroundCleanExpiredDiskCache()// 后台清理,但不需要回调

    // 判定图片是否存在

    let cached = cache.isImageCached(forKey:"test")

     

    // 监听数据移除

    NotificationCenter.default.addObserver(self, selector:#selector(cleanDiskCache), name: NSNotification.Name.init("KingfisherDidCleanDiskCacheNotification"), object:nil)

    ==========下载图片带进度

     

    下载图片:

     

    图片加载ImageDownloader使用

       从名字就可以很清楚的知道,这个类就是用来下载图片的,它为我们提供了一些头的设置(比如说你有些图片是需要认证用户才能下载的);安全设置:我们在下载图片时哪些Host是可信任的;下载超时设置;下载回调等。

    let downloader = ImageDownloader.default

    // 设置可信任的Host

    let hosts: Set<String> = ["http://xxxxx.com","http://#####.com"]

    downloader.trustedHosts =hosts

    // 设置sessionConfiguration

    downloader.sessionConfiguration =URLSessionConfiguration.default

    // 设置代理,详情参考 ImageDownloaderDelegate

    downloader.delegate =self

    // 下载超时设置

    downloader.downloadTimeout =20

    // 下载图片

    let retriveTask = downloader.downloadImage(with: URL(string: "http://xxx.com")!, retrieveImageTask:nil, options: nil, progressBlock:nil, completionHandler: {

        (image, error, imageURL, originalData) in

    })

    // 取消下载

    retriveTask?.cancel()

     

    =====================直接下载设置图片

     

    使用:

    引入import Kingfisher

     

     

     

    •  let imagev:UIImageView=UIImageView.init(frame:CGRect(x:0,y:50,width:100,height:100))

     

            view.addSubview(imagev)

            imagev.kf.setImage(with:ImageResource(downloadURL:URL.init(string:"http://www.ahwofu.com/upload/201710/1508813630.jpg")!))

     

    ============主控制器KingfisherManager使用

     

       KingfisherManager是连接ImageDownloader与ImageCache的,所以你可以通过manager得到 downloader与cache,并且还能改设置加载选项,当然你也可以设置其他的ImageDownloader与ImageCache到你的Manager。

    let kfManager = KingfisherManager.shared

    // 通过manager 获取cache

    cache = kfManager.cache

    // 通过manager 获取downloader

    downloader = kfManager.downloader

    // 设置options, 你可以设置你的newCache/newDownloader以及其他配置

    kfManager.defaultOptions = [.targetCache(newCache), .downloader(newDownloader), .forceRefresh, .backgroundDecode, .onlyFromCache, .downloadPriority(1.0)]

    // 检索

    let resource = ImageResource(downloadURL:URL(string: "http://xxxx.com")!, cacheKey:"text")

    let retriveImageTask = kfManager.retrieveImage(with: resource, options: nil, progressBlock: nil, completionHandler: {

        (image, error, cacheType, imageURL) in

        if error == nil {

            print("检索图片成功")

        } else {

            print("检索图片失败")

        }

    })

    retriveImageTask.cancel()

     

    ================

     

    Kingfisher 提供了UIButton与UIImageView的扩展,使你可以通过直接设置图片URL来显示,两者用法差不多,以UIImageView为例:

    // 设置网络图片

    imageView.kf.setImage(with: ImageResource(downloadURL: imageURL!))

     

    imageView.kf.setImage(with: ImageResource(downloadURL: imageURL!), placeholder:UIImage(named: "test"), options:nil, progressBlock: nil, completionHandler: nil)

     

    // UIImageView 也可以设置取消加载 (两种方式)

    imageView.kf.cancelDownloadTask()

     

    let retriveImaeTask = imageView.kf.setImage(with:ImageResource(downloadURL: imageURL!))

    retriveImaeTask.cancel()

     

    Kingfisher

    Kingfisher

    在oc时代有个非常强大图片缓存处理的库SDWebImage,swift中现在也有个不错的图片处理的库----Kingfisher

    此库是由onevcat大神所写,感谢大神的无私奉献。

    大神关于swift的理解非常深刻,http://swifter.tips/ 我最近正在拜读,推荐给大家。深入理解swift语言。

    下面简单介绍下这个库的一些用法。其实都在大神github地址上有所讲解
    https://github.com/onevcat/Kingfisher

    Kingfisher文档地址:http://cocoadocs.org/docsets/Kingfisher/1.6.1/

    Kingfisher库下载图片默认是带缓存的

    最简单的使用

    import Kingfisher
    imageView.kf_setImageWithURL(NSURL(string: "http://your_image_url.png")!)
    

    这边我也是满心欢喜的在百度随便找了个图测试,但是并没有down下来。。用https就可以,看下控制台信息好像是安全之类的问题,网上查了下 解决了

    http 开头连接不能读取解决方案 ,在info.plist里加上下面这段

    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    </plist>
    

    或者 去配置一个Dictionary类型的NSAppTransportSecurity 子item是Boolean类型NSAllowsArbitraryLoads value是YES

    OK,解决。

    我是随便在baidu找了一张卡通图
    http://pic29.nipic.com/20130512/12428836_110546647149_2.jpg
    第一次回加载一会,第二次就不会加载了。

    添加默认图

    我们大多会在tableviewCell中的头像上使用,加载的时候显示空空的有点怪。作者很贴心的给我们提供了默认图参数

    testImag.kf_setImageWithURL(NSURL(string: "http://your_image_url.png")!, placeholderImage: UIImage(named: "mrt"))
    

    这时候在加载的时候就会显示默认图

    默认情况下Kingfisher使用url当做cache(缓存)的key。 不过你也可以自定义这个key 。

    let URL = NSURL(string: "http://your_image_url.png")!
    let resource = Resource(downloadURL: URL, cacheKey: "your_customized_key")
    imageView.kf_setImageWithResource(resource)
    

    首先会在内存或者硬盘读取“your_customized_key”的缓存 ,如果没有找到,就尝试从URL里download,down下来在用你提供的key保存起来供下次使用

    一些选项

    Kingfisher 默认先从内存和硬盘搜 ,如果没找到才去URL down,当然你也可以强制它每次从URL down,忽略缓存

    imageView.kf_setImageWithURL(NSURL(string: "your_image_url")!, placeholderImage: nil, optionsInfo: [.Options: KingfisherOptions.ForceRefresh])
    

    还有一些其他的选项控制缓存等级的,这些可以看文档

    你还可以自定义缓存取代默认的。

    let myCache = ImageCache(name:"my_cache")
    imageView.kf_setImageWithURL(NSURL(string: "your_image_url")!, placeholderImage: nil, optionsInfo: [.TargetCache: myCache])
    

    这个在某种情况下你想使用指定缓存的时候会有用

    当然,还可以设置一些动画

    imageView.kf_setImageWithURL(NSURL(string: "your_image_url")!,
                             placeholderImage: nil,
                                  optionsInfo: [.Transition: ImageTransition.Fade(1)])
    

    回调

    有时候需要下载完成后做点事情,这些逻辑可以写在回调中

    imageView.kf_setImageWithURL(NSURL(string: "your_image_url")!, 
      placeholderImage: nil, 
      optionsInfo: nil, 
      progressBlock: { (receivedSize, totalSize) -> () in 
      println("Download Progress: \(receivedSize)/\(totalSize)") }, 
      completionHandler: { (image, error, imageURL) -> () in 
      println("Downloaded and set!") 
    })
    

    取消任务

    所有 kf_setImageWithURL 都返回 RetrieveImageTask类型的对象 , 你可以调用cancel方法取消正在执行的任务

    let task = imageView.kf_setImageWithURL(NSURL(string: "http://your_image_url.png")!)
    task.cancel()
    

    下载和缓存系统

    我们可以自定义下载和缓存系统的一写属性,比如 超时时间

    let downloader = KingfisherManager.sharedManager.downloader
    
    // 修改超时时间
    downloader.downloadTimeout = 5
    
    
    let cache = KingfisherManager.sharedManager.cache
    
    // 设置硬盘最大缓存50M ,默认无限
    cache.maxDiskCacheSize = 50 * 1024 * 1024
    // 设置硬盘最大保存3天 , 默认1周
    cache.maxCachePeriodInSecond = 60 * 60 * 24 * 3
    
    // 获取硬盘缓存的大小
    cache.cache.calculateDiskCacheSizeWithCompletionHandler { (size) -> () in      
        println("disk size in bytes: \(size)")
    }
    

    内存的缓存在app退出或者后台运行或者内存警告的时候会被清除 ,硬盘在满足上面的条件才会被清理 , 当然也可以手动清理

    //清理内存缓存
    cache.clearMemoryCache()
    
    // 清理硬盘缓存,这是一个异步的操作
    cache.clearDiskCache()
    
    // 清理过期或大小超过磁盘限制缓存。这是一个异步的操作
    cache.cleanExpiredDiskCache()
    

     

     

     

     

    Kingfisher是一个轻量的下载和缓存网络图片库。下载和缓存是异步进行操作,已经下载好的图片会缓存在内存和本地,极大得提高app的体验。

     

    编码之前

    导入 Kingfisher

    推荐使用CocoaPods进行导入,CocoaPods是一个负责管理iOS项目中第三方开源库的工具,安装CocoaPods之后使用命令行就能轻松地对所有第三方开源库进行安装和更新,而不需要每次上GitHub去下载。 
    CocoaPods的安装过程传送门:iOS 9 导入类库全面详尽过程(Ruby安装->CocoaPods安装->导入类库) 
    手动安装:GitHub-Kingfisher主页

    装好CocoaPods后,修改Podfile文件内容为如下:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :ios, '9.0'
    use_frameworks!
    
    target 'Web' do
    pod 'Kingfisher', '~> 2.4'
    end
    xcodeproj 'Desktop/Web/Web.xcodeproj'

    target后面为工程名,最后一行为工程路径(这里的Web是我的工程名)

    再执行命令:

    $ pod install

    其他操作

    另外还需要在Target->工程名->Build Settings->Search Paths->User Header Search Paths处添加Kingfisher所在的目录:

    这里写图片描述

    最后在你需要用到Kingfisher的类中加上:

    import Kingfisher
    • 1

    基础操作

            let url = NSURL(string: "http://www.51work6.com/service/download.php?email=scuxiatian@foxmail.com&FileName=test1.jpg")!;
    
            //打开该url地址的图片
            imageView.kf_setImageWithURL(url)
    
            //如果打开失败,打开placeholderImage参数的图片
            imageView.kf_setImageWithURL(url, placeholderImage: UIImage(named: "sps.png"))
    
            //打开资源中的图片,如果本地缓存中没有,将从url地址下载,以关键字"MyImage"保存起来,以便下次使用
            let resource = Resource(downloadURL: url, cacheKey: "MyImage");
            imageView.kf_setImageWithResource(resource);

    运行效果如下:

    这里写图片描述

    使用optionsInfo参数

            //强制刷新,无论图片是否已在缓存中,到从url地址重新下载
            imageView.kf_setImageWithURL(url, placeholderImage: nil, optionsInfo: [.ForceRefresh])
    
            //自定义关键字为"MyImage"的ImageCache
            let myCache = ImageCache(name: "MyImage");
            //将打开图片存入指定关键字的缓存中,而不是默认缓存
            imageView.kf_setImageWithURL(url, placeholderImage: nil, optionsInfo: [.TargetCache(myCache)])
    
            //图片以淡入方式出现,动画持续1秒
            imageView.kf_setImageWithURL(url, placeholderImage: nil, optionsInfo: [.Transition(ImageTransition.Fade(1))])
    
            //optionsInfo参数可以同时接受多个条件
            imageView.kf_setImageWithURL(url, placeholderImage: nil, optionsInfo: [.ForceRefresh,.TargetCache(myCache),.Transition(ImageTransition.Fade(1))])
    

    回调函数

            imageView.kf_setImageWithURL(url, placeholderImage: nil, optionsInfo: nil, 
            //进度回调函数
            progressBlock: { (receivedSize, totalSize) in
                print(receivedSize / totalSize)
            //完成回调函数
            { (image, error, cacheType, imageURL) in
                print("complete")
            }

    取消任务

    如果下载的图片不再使用可以停止任务,多用于tableView和collectionview中的cell,当图片还没下载完成时,用户就滑动界面导致cell消失的情况。

            imageView.kf_setImageWithURL(url)
            //停止图片的取回
            imageView.kf_cancelDownloadTask();

    也可以利用kf_setImageWithURL函数的返回值(类型为RetrieveImageTask)来进行更多的管理操作

            let task = imageView.kf_setImageWithURL(url)
            //取消任务
            task.cancel();

    下载器

    自定义下载器参数

            //获取下载器
            let downloader = KingfisherManager.sharedManager.downloader
            //设置超时时间,默认为15妙
            downloader.downloadTimeout = 5
            //requestModifier中的内容会在下载之前开始执行
            downloader.requestModifier = {
                (request: NSMutableURLRequest) in
                self.imageView.image = UIImage(named: "sps.png")
            }
            //设置信任host
            downloader.trustedHosts = Set(["httpbin.org"])

    缓存系统

    自定义缓存参数

            //获取缓存
            let cache = KingfisherManager.sharedManager.cache
            //设置最大磁盘缓存为50Mb,默认为无限制
            cache.maxDiskCacheSize = 50 * 1024 * 1024
            //设置最大缓存时间为1天,默认为1周
            cache.maxCachePeriodInSecond = 60 * 60 * 24
            //计算缓存占用的磁盘大小
            cache.calculateDiskCacheSizeWithCompletionHandler { (size) in
                print(size)
            }
            //清空存储器缓存
            cache.clearMemoryCache()
            //清空磁盘缓存
            cache.clearDiskCache()
            //清空失效和过大的缓存
            cache.cleanExpiredDiskCache()

    预取

    将一些图片在显示到屏幕上之前,先预取到缓存。主要用于当你可以预知接下来会用到图片资源时,避免多次请求。

            let urlString1 = "http://www.51work6.com/service/download.php?email=scuxiatian@foxmail.com&FileName=test1.jpg"
            let urlString2 = "http://www.51work6.com/service/download.php?email=scuxiatian@foxmail.com&FileName=test2.jpg"
    
            let urls = [urlString1,urlString2].map{NSURL(string: $0 )!}
            let prefetcher = ImagePrefetcher(urls: urls, optionsInfo: nil, progressBlock: nil) { (skippedResources, failedResources, completedResources) in
                print("These resources are prefetched:\(completedResources)")
            }
            //开始预取,预取成功的图片处理方式跟ImageCache中缓存的图片一样
            prefetcher.start()
            //停止预取
            prefetcher.stop()

     

     

    动态图片

    加载动态图片只需要加上一行代码,设置imageView为AnimatedImageView,不设置也能加载,但是在动态图片较大的时候推荐进行该设置。

            imageView = AnimatedImageView()
            imageView.kf_setImageWithURL(url)

    深入学习

    这里列出了Kingfisher大多数操作,如果想要深入学习Kingfisher,可以前往GitHub-Kingfisher主页

     

     

    展开全文
  • 如果每次都去请求,不但浪费时间,用户体验也会变差,所以移动应用都会做离线缓存处理,其中已图片缓存最为常见。 但是时间长了,离线缓存会占用大量的手机空间,所以清除缓存功能基本是移动应用开发的标配。 ...
  • KTVHTTPCache 是一个处理 HTTP 网络缓存的框架。设计之初是为了解决音视频在线播放的缓存问题。但其应用场景不仅限于音视频在线播放,也可以用于图片加载、文件下载、普通网络请求等场景。
  • 无限循环轮播器:本地图片,网络图片(缓存)
  • Swift 常用的框架有Alamofire,D3Model,Kingfisher,SnapKit,ZLSwiftRefresh。
  •   let urlStr = NSURL(string: "https://s.yimg.com/dh/ap/default/130909/y_200_a.png") let request = NSMutableURLRequest(url: urlStr as! URL); /** * .设置缓...
  • 最近项目中需要用到网络图片加载,在网上找了很多图片加载的文章,不过感觉都不怎么方便。后来找到AlamofireImage这个库,使用起来非常简单,readme也非常清晰,记录一下使用过程,希望帮到需要的人,本文代码使用的...
  • 1. 很多APP都会涉及到资讯或帖子或主题详情页的界面,其中就涉及到cell加载网络图片的开发问题. 2. 最容易想到的思路就是把URL直接传递给cell,让cell的imageView控件直接使用SDWebImage下载,然后去展示. 这个思路...
  • 图片------------------------------------------------------------------------------------ • PhotoPicker swift图片选择 • BSImagePicker ios图像选择...处理网络图片缓存的库 • ImageScout最小网络代
  • // YDWGIFView.swift // Project // // Created by cptech on 2017/6/19. // Copyright © 2017年 CPTECH_ydw. All rights reserved. //import UIKit import ImageIO import QuartzCoreclass YDWGIFView: UIView
  • ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)➤GitHub地址:...
  • Kingfisher 一个用于从Web下载并缓存图片的轻量级、纯Swift库。这个项目类似于SDWebImage,但采用纯Swift开发。
  • 这是一个swift写的图片浏览器,只要传一个数组可以轻松展示本地图片和网络图片,还可以指定展示第几页,还是实现了图片的缓存,避免重复下载
  • 前言我们常见的一些广告位、图片轮播都是可以无限轮播的,以前参考文章 iOS开发系列–无限循环的...先看一下效果图,这里分为本地图片、网络图片、相册三个部分来实现,首先看一下本地效果。其实本地的实现是最简单的
1 2 3 4 5 ... 20
收藏数 3,385
精华内容 1,354
关键字:

swift 缓存网络图片