iOS 轻量化动态图像下载缓存框架实现

一、背景

日常开发过程中,图片的下载会占用大量的带宽,图片的加载会消耗大量的性能和内存,正确的使用图片显得尤为重要。
同样也经常需要在各类型控件上读取网络图片和处理本地图片,例如:UIImageView、UIBtton、NSImageView、NSButton等等。
这时候有个从网络下载和缓存图像库就会便利太多太多,很多人这时候会说,对于这块也有很多比较优秀的开源库,比如 KingfisherYYWebImageSDWebImage等等。

0 0. 框架由来,

  • 本来之前呢只是想实现一个如何播放GIF,于是乎就出现第一版对任意控件实现播放GIF功能,这边只需要支持 AsAnimatable 即可快速达到支持播放GIF功能;
  • 后面Boss居然又说需要对GIF图支持注入滤镜功能,于是乎又修改底层,对播放的GIF图实现滤镜功能,于是之前写的滤镜库 Harbeth 即将闪亮登场;
  • 然后Boss又说,首页banner需要图像和GIF混合显示,索性就又来简单封装显示网络图像,然后根据 AssetType 来区分是属于网图还是GIF图,以达到混合显示网络图像和网络GIF以及本地图像和本地GIF混合播放功能;
  • 起初也只是简单的去下载资源Data用于显示图像,这时候boss又要搞事情了,图像显示有点慢,于是乎又开始写网络下载模块 DataDownloader 和磁盘缓存模块 Cached ,对于已下载的图像存储于磁盘缓存方便后续再次显示,同样的网络链接地址同时下载时不会重复下载,下载完成后统一分发响应,对于下载部分资源进行断点续载功能;
  • 慢慢越写越发现这玩意不就是一个图像库嘛,so 它就这么的孕育而生了!!!

备注:作为参考对象,当然这里面会有一些 Kingfisher 的影子,so 再次感谢猫神!!也学到不少新东西,Thanks!

先贴地址:https://github.com/yangKJ/ImageX

请添加图片描述
待完成功能:

  • 网络资源分片下载
  • 控制下载最大并发量
  • 低数据模式
  • 图像解码优化
  • 位图展示动画效果

实现方案

这边主要就是分为以下几大模块,网络下载模块资源缓存模块动态图播放模块控件展示模块解码器模块 以及 配置模块等;

这边对于资源缓存模块,已独立封装成库 Lemons 来使用,支持磁盘和内存缓存,同时也支持对待存储数据进行压缩处理从而占用更小存储空间,同时也会对磁盘数据进行时间过期和达到最大缓存空间的自动清理。

如何播放动态图像

对于这块,核心其实就是使用 CADisplayLink 不断刷新和更新动画帧图,然后对不同的控件去设置显示图像资源;

主要就是针对不同对象设置显示内容:

  • UIImageView:imagehighlightedImage
  • NSImageVIew:image
  • UIButton:imagebackgroundImage
  • NSButton:imagealternateImage
  • WKInterfaceImage:image

对于UIView没有上述属性显示,so 这边对layer.contents设置也是同样能达到该效果。

如何下载网络资源

对于网络图像显示,不可获取的就是对于资源的下载。

最开始的简单版,

let task = URLSession.shared.dataTask(with: url) {
   
    (data, _, error) in
    switch (data, error) {
   
   
    case (.none, let error):
        failed?(error)
    case (let data?, _):
        DispatchQueue.main.async {
   
   
            self.displayImage(data: data, filters: filters, options: options)
        }
        let zipData = options.cacheDataZip.compressed(data: data)
        let model = CacheModel(data: zipData)
        storager.storeCached(model, forKey: key, options: options.cacheOption)
    }
}
task.resume()

鉴于boss说的显示有点慢,能优化不。于是开始就对网络下载模块开始优化,网络数据共享和断点续下功能就孕育而生,后续再来补充分片下载功能,进一步提升网络下载速率。

网络共享

  • 对于网络共享,这边其实就是采用一个单例 Networking 来设计,然后对需要下载的资源和回调响应进行存储,以链接地址md5作为key来管理查找,当数据下载回来之后,分别分发给回调响应即可,同时删除缓存的下载器和回调响应对象;

核心代码,下载过来的数据分发处理。

let downloader = DataDownloader(request: request, named: key, retry: retry, interval: interval) {
   
   
    for call in cacheCallBlocks where key == call.key {
   
   
        switch $0 {
   
   
        case .downloading(let currentProgress):
            let rest = DataResult(key: key, url: url, data: $1!, response: $2, downloadStatus: .downloading)
            call.block.progress?(currentProgress)
            call.block.download(.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值