为了账号安全,请及时绑定邮箱和手机立即绑定

Nuke框架详细解析(一) —— 基本概览(一)

标签:
Java

版本记录

版本号时间
V1.02018.12.27 星期四

前言

OC对有一个很棒的网络图片加载控件SDWebImage,那么Swift中呢,如果要加载远程网络图片呢?这里接下来几篇就给大家介绍一个Swift中用于加载网络图片的框架 —— Nuke

概览

webp

webp

首先我们看一下作者

webp

它是强大的图像加载和缓存系统。 它使得将图像加载到视图中的任务非常简单,同时还支持更高要求的应用程序的高级功能。

  • 快速LRU内存缓存,本机HTTP磁盘缓存和自定义主动LRU磁盘缓存

  • 逐步图像加载(渐进式JPEG和WebP)

  • 可恢复的下载,请求优先级,重复数据删除,速率限制等

  • AlamofireWebPGifuFLAnimatedImage扩展

  • RxNuke - RxSwift扩展

  • 使用Preheat自动prefetching(在iOS 10中已弃用)


Getting Started

更多信息可在Documentation目录和完整的API Reference中找到。 当您准备好安装Nuke时,您可以遵循Installation Guide - 支持所有主要的包管理器。


Quick Start

1. Load Image into Image View

您可以使用一行代码将图像加载到图像视图中。

Nuke.loadImage(with: url, into: imageView)

Nuke将自动加载图像数据,在后台解压缩,将图像存储在内存缓存中并显示它。

要学习ImagePipelinesee the dedicated section

当您为视图请求新图像时,先前未完成的请求将被取消,图像将设置为nil。 视图dealloc时,请求也会自动取消。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    ...
    Nuke.loadImage(with: url, into: cell.imageView)
    ...
}

2. Placeholders, Transitions and More

使用options参数(ImageLoadingOptions)自定义图像的加载和显示方式。 您可以提供占位符,选择其中一个内置过渡(transition)或提供自定义过渡。 使用过渡时,请注意UIKit可能会保留对图像的引用,以防止因为长动画或一次加载多个过渡而被移除。

Nuke.loadImage(    with: url,    options: ImageLoadingOptions(        placeholder: UIImage(named: "placeholder"),        transition: .fadeIn(duration: 0.33)
    ),    into: imageView)

有一个很常用的场景:当占位符(或失败的图像)需要以与用于加载的图像不同的content mode显示时。

let options = ImageLoadingOptions(
    placeholder: UIImage(named: "placeholder"),    failureImage: UIImage(named: "failure_image"),    contentModes: .init(
        success: .scaleAspectFill,        failure: .center,        placeholder: .center
    )
)

Nuke.loadImage(with: url, options: options, into: imageView)

要使应用程序中的所有图像视图共享相同的行为,请修改ImageLoadingOptions.shared

如果ImageLoadingOptions缺少您需要的功能,请直接使用ImagePipeline。 如果您认为每个人都可以从此功能中受益,PRs是不错的选择。

3. Image Requests

每次请求都是ImageRequest表示的,一次请求可以有URL或者URLRequest创建。

var request = ImageRequest(url: url)// var request = ImageRequest(urlRequest: URLRequest(url: url))// Change memory cache policy:request.memoryCacheOptions.isWriteAllowed = false// Update the request priority:request.priority = .high

Nuke.loadImage(with: request, into: imageView)

4. Process an Image

使用特殊的ImageRequest初始化器改变图片的尺寸。

// Target size is in pixels.ImageRequest(url: url, targetSize: CGSize(width: 640, height: 320), contentMode: .aspectFill)

使用processed(key:closure:)方法执行自定义转换。 以下是使用Toucan创建circular avatar的方法。

ImageRequest(url: url).process(key: "circularAvatar") {
    Toucan(image: $0).maskWithEllipse().image
}

所有这些API都建立在ImageProcessing协议之上,您也可以使用它来实现自定义处理器。 请记住,ImageProcessing还需要遵守Equatable,这有助于Nuke识别内存缓存中的图像。

Nuke中使用Core Image,请参考Core Image Integration Guide


Advanced Usage

1. Image Pipeline

直接使用ImagePipeline加载图像,不用view

let task = ImagePipeline.shared.loadImage(
    with: url,
    progress: { _, completed, total in
        print("progress updated")
    },
    completion: { response, error in
        print("task completed")
    }
)

任务可用于监视下载进度,取消请求以及动态更新下载优先级。

task.cancel()task.setPriority(.high)

有关ImagePipeline的更多信息,请see the dedicated section

2. Configuring Image Pipeline

除了使用共享的ImagePipeline实例外,您还可以创建自己的实例。

let pipeline = ImagePipeline {
    $0.dataLoader = ...
    $0.dataLoadingQueue = ...
    $0.imageCache = ...
    ...
}// When you're done you can make the pipeline a shared one:ImagePipeline.shared = pipeline

3. Memory Cache

默认NukeImagePipeline有两个缓存层。

首先,有一个缓存专门用来存储用来准备显示的处理过的图像。 您可以直接访问此缓存:

// Configure cacheImageCache.shared.costLimit = 1024 * 1024 * 100 // 100 MBImageCache.shared.countLimit = 100ImageCache.shared.ttl = 120 // Invalidate image after 120 sec// Read and write imageslet request = ImageRequest(url: url)
ImageCache.shared[request] = imagelet image = ImageCache.shared[request]// Clear cacheImageCache.shared.removeAll()

4. HTTP Disk Cache

为了存储未处理的图像数据,Nuke使用URLCache实例:

// Configure cacheDataLoader.sharedUrlCache.diskCapacity = 100DataLoader.sharedUrlCache.memoryCapacity = 0// Read and write responseslet request = ImageRequest(url: url)let _ = DataLoader.sharedUrlCache.cachedResponse(for: request.urlRequest)
DataLoader.sharedUrlCache.removeCachedResponse(for: request.urlRequest)// Clear cacheDataLoader.sharedUrlCache.removeAllCachedResponses()

5. Aggressive Disk Cache

自定义LRU磁盘缓存可用于快速可靠的主动数据缓存(忽略HTTP cache control)。 您可以使用管道配置启用它。

$0.dataCache = try! DataCache(name: "com.myapp.datacache")// On Swift 4.1 and lower you'll also need to provide a `FilenameGenerator`.

如果启用了主动磁盘缓存,请确保还禁用本机URL缓存(请参阅DataLoader),否则最终可能会存储两次相同的映像数据。

DataCache类型实现公共DataCaching协议,可用于实现自定义数据缓存。

6. Prefetching Images

预先Prefethcing图像可以减少用户的等待时间。 Nuke提供了一个ImagePreheater来做到这一点:

let preheater = ImagePreheater()
preheater.startPreheating(with: urls)// Cancels all of the preheating tasks created for the given requests.preheater.stopPreheating(with: urls)

需要权衡,prefetching会占用用户的数据,并对CPU和内存造成额外压力。 要减少CPU和内存使用量,您可以选择仅将磁盘缓存作为prefetching目标:

// The preheater with `.diskCache` destination will skip image data decoding// entirely to reduce CPU and memory usage. It will still load the image data// and store it in disk caches to be used later.let preheater = ImagePreheater(destination: .diskCache)

为确保prefetching请求不会干扰正常请求,最好降低其优先级。

您可以将NukePreheat库结合使用,该库可自动preheating  UICollectionViewUITableView中的内容。 在iOS 10.0上,您可能希望使用iOS提供的新prefetching APIs

7. Progressive Decoding

要使用渐进式图像加载,您需要启用渐进式解码的管道。

let pipeline = ImagePipeline {    $0.isProgressiveDecodingEnabled = true}

就是这样,你可以开始观察管道产生的图像。 进度处理程序也可用作渐进式图像处理程序。

let imageView = UIImageView()let task = ImagePipeline.shared.loadImage(    with: url,    progress: { response, _, _ in
        imageView.image = response?.image
    },    completion: { response, _ in
        imageView.image = response?.image
    }
)

请参阅"Progressive Decoding"演示,了解渐进式JPEG在实践中的应用。

8. Animated Images

Nuke使用animatedImageData属性扩展UIImage。 如果通过将ImagePipeline.Configuration.isAnimatedImageDataEnabled设置为true来启用它,则管道将开始将原始图像数据附加到动画图像(内置解码器现在仅支持GIF)。

在计算缓存项目的成本时,ImageCache会将animatedImageData考虑在内。 ImagePipeline不会将处理器应用于带有动画数据的图像。

没有内置的方法来渲染这些图像,但有两种可用的集成:FLAnimatedImageGifu,它们既快速又高效。

GIF不是传输和显示动画图像的最有效格式。 目前的最佳做法是use short videos instead of GIFs(例如MP4WebM)。 演示项目中有一个PoC,它使用Nuke加载,缓存和显示MP4视频。

9. WebP

WebP支持由Ryo Kosuge构建的Nuke WebP Plugin插件提供。 请按照repo中的说明进行安装。

10. RxNuke

RxNuke为Nuke添加了RxSwift扩展,并支持许多常见用例:

以下是将go flow log加载到高分辨率是多么容易的示例:

let pipeline = ImagePipeline.shared
Observable.concat(pipeline.loadImage(with: lowResUrl).orEmpty,
                  pipeline.loadImage(with: highResUtl).orEmpty)
    .subscribe(onNext: { imageView.image = $0 })
    .disposed(by: disposeBag)

Image Pipeline

Nuke的图像管道由大约五个阶段组成,可以使用以下协议进行自定义:

webp



作者:刀客传奇
链接:https://www.jianshu.com/p/d2a34eb67d8c


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消