这是一个可以方便地将图片显示到UI上的图片缓存库。
项目 | 内容 |
---|---|
支持的 iOS 版本 | iOS 15.0 及以上 |
支持的 Swift 版本 | 5.9 及以上 |
使用的技术 | Swift, Swift Concurrency |
项目 | 链接 |
---|---|
케어밋 (Care Meet - assume this is the intended translation) | App Store |
soma코인뷰어 (Soma Coin Viewer - assuming this is the intended translation) | GitHub |
通过访问 SimpleImageProvider.shared
单例对象,您可以使用该库的功能。
建议您在启动应用程序之前设置内存缓存大小、磁盘缓存大小以及溢出策略。
如果在其他运行时空间中执行此代码,可能会发生意外的并发问题。
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
SimpleImageProvider.shared.requestConfigureState(
maxCacheImageCount: 50,
maxDiskImageCount: 100,
percentToDeleteWhenDiskOverflow: 20.0
)
return true
}
}
实现了可以在 SwiftUI 中使用的 SimpleImage View
。
LazyVGrid(columns: columns) {
ForEach(items, id: \.self) { item in
SimpleImage(
url:"your image url",
size: .init(width: 100, height: 100),
fadeOutduration: 0
)
.frame(width: 100, height: 100)
.background(Color.gray.opacity(0.5))
.cornerRadius(5)
}
}
可以作为 UIImageView 的扩展轻松访问。
func setImage(url: String, size: CGSize) {
uiImageView
.simple
.setImage(url: url, size: size, fadeOutDuration: 0.2)
}
如果不是使用 UI 库而是通过代码访问,请使用单例对象。
单例对象本身已针对并发进行了优化。
await SimpleImageProvider.shared.requestImage(...)
内存缓存:使用 NSCache
将常用图像缓存到内存中。
磁盘缓存:使用 FileManager
将图像缓存到磁盘,并使用 LRU 方式进行管理。
降采样:在请求图像时,使用传递的 CGSize
对接收到的图像进行采样。
※ 采样后的图像将被缓存。
缓存到磁盘和内存的图像都是经过降采样处理后的图像。
即使是相同的图像,也会根据采样结果进行不同的缓存。
您可以在下面的缓存键值中看到包含了降采样大小。
func createKey(url: String, size: CGSize?) -> String {
var keyString = url
if let size {
let width = size.width
let height = size.height
keyString += "\(width)x\(height)"
}
return keyString
}
图像降采样将下载的数据缓冲区更改为 CGImageSource
。
通过将 CGImageSource
更改为特定大小的缩略图(小于/缩减的原始图像),来执行降采样。
※ 为了直接管理图像缓存,我禁用了图像源创建和缩略图创建时的所有其他缓存选项。
func downSamplingImage(dataBuffer: Data, size: CGSize) async -> UIImage? {
let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
guard let imageSource = CGImageSourceCreateWithData(dataBuffer as CFData,
imageSourceOptions) else {
return nil
}
let biggerLength = max(size.width, size.height)
let scale = await UIScreen.main.scale
let maxDimensionInPixels = biggerLength * scale
let downsampleOptions = [
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceShouldCacheImmediately: false,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels
] as CFDictionary
guard let downsampledImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0,
downsampleOptions) else {
return nil
}
let image = UIImage(cgImage: downsampledImage)
return image
}
---
title: SimpleImageProvider flowchart
---
flowchart LR
requestimage --> SimpleImageProvider
SimpleImageProvider --> checkMemoryCache
checkMemoryCache --> checkDiskCache
checkDiskCache --> ImageDownloader
ImageDownloader --> CacheImage
图像获取过程如下,如果图像获取失败,则跳转到下一步
。
---
title: SimpleImageProvider class diagram
---
classDiagram
class SimpleImageProvider {
+ requestImage(url, size) UIImage?
+ requestConfigureState(cacheSize)
}
class ImageModifier {
+ downSamplingImage(data, size) UIImage?
+ convertDataToUIImage(data)
}
class ImageDownloader {
+ requestImageData(url) Data?
}
class ImageCacher {
+ requestImage(url, size) UIImage?
+ cacheImage(url, size, image)
}
class DiskCacher
class MemoryCacher
ImageCacher o-- DiskCacher
ImageCacher o-- MemoryCacher
SimpleImageProvider --|> MemoryCacher : 1.check memeory cache
SimpleImageProvider --|> DiskCacher : 2.check disk cache
SimpleImageProvider --|> ImageDownloader : 3.request download & data buffer
SimpleImageProvider --|> ImageModifier : 4.request image downsampling or convert data to image