RemoteImage

Swift 5.3 Platforms Current Version Build status Code coverage License

这个 Swift 包提供了一个围绕现有 SwiftUI Image view 的包装视图,增加了对显示和缓存远程图片的支持。此外,您可以指定加载和错误视图。

您可以从特定的 URLiCloud(通过 PHAsset 标识符)显示图片。

💡 安装

在 Xcode 中使用其 Github 仓库 url 添加此 Swift 包。(File > Swift Packages > Add Package Dependency...)

🧭 如何使用

只需将远程图片 URL 或 PHAsset 的本地标识符,以及用于错误、图片和加载状态的 ViewBuilder 传递给初始化器即可。 就是这么简单 🎉

通过 RemoteImageService.cache.removeAllObjects() 清除图片缓存。

📖 示例

以下代码充分突出了此视图的简洁性

URL 示例

let url = URL(string: "https://images.unsplash.com/photo-1524419986249-348e8fa6ad4a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80")!

RemoteImage(type: .url(url), errorView: { error in
    Text(error.localizedDescription)
}, imageView: { image in
    image
    .resizable()
    .aspectRatio(contentMode: .fit)
}, loadingView: {
    Text("Loading ...")
})

PHAsset 示例

RemoteImage(type: .phAsset(localIdentifier: "541D4013-D51C-463C-AD85-0A1E4EA838FD"), errorView: { error in
    Text(error.localizedDescription)
}, imageView: { image in
    image
    .resizable()
    .aspectRatio(contentMode: .fit)
}, loadingView: {
    Text("Loading ...")
})

自定义 RemoteImageURLDataPublisher

默认情况下,底层使用 URLSession.shared 作为 RemoteImageURLDataPublisher 来获取指定 URL 的图片。 您可以通过 remoteImageURLDataPublisher 参数指定自定义的 publisher。 例如,您可以这样为 RemoteImage 视图添加低数据模式的支持。

let url = URL(string: "https://images.unsplash.com/photo-1524419986249-348e8fa6ad4a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80")!

RemoteImage(type: .url(url), remoteImageURLDataPublisher: {
    let configuration = URLSessionConfiguration.default
    // Enable low data mode support
    configuration.allowsConstrainedNetworkAccess = false
    return URLSession(configuration: configuration)
}(), errorView: { error in
    Text(error.localizedDescription)
}, imageView: { image in
    image
    .resizable()
    .aspectRatio(contentMode: .fit)
}, loadingView: {
    Text("Loading ...")
})

自定义 RemoteImageService

如果您想完全控制负责管理视图状态和获取图片的服务,您可以将一个符合 RemoteImageService 协议的对象传递给相关的初始化器。

final class CustomService: RemoteImageService { ... }

let url = URL(string: "https://images.unsplash.com/photo-1524419986249-348e8fa6ad4a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80")!

RemoteImage(type: .url(url), service: CustomService(), errorView: { error in
    Text(error.localizedDescription)
}, imageView: { image in
    image
    .resizable()
    .aspectRatio(contentMode: .fit)
}, loadingView: {
    Text("Loading ...")
})

除此之外,您还可以通过创建默认内置 RemoteImageService 的实例并使用上述初始化器,来使用 Swift 中引入的新的 @StateObject 属性包装器。

@StateObject var service = DefaultRemoteImageServiceFactory.makeDefaultRemoteImageService()
// or
@StateObject var service = DefaultRemoteImageServiceFactory.makeDefaultRemoteImageService(remoteImageURLDataPublisher: yourRemoteImageURLDataPublisher)

let url = URL(string: "https://images.unsplash.com/photo-1524419986249-348e8fa6ad4a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80")!

RemoteImage(type: .url(url), service: service, errorView: { error in
    Text(error.localizedDescription)
}, imageView: { image in
    image
    .resizable()
    .aspectRatio(contentMode: .fit)
}, loadingView: {
    Text("Loading ...")
})

自定义缓存

RemoteImageService 使用默认缓存。 要使用自定义缓存,只需遵循 RemoteImageCache 协议并在类型 RemoteImageService 上设置它。

RemoteImageService.cache = yourCache

自定义缓存键

默认缓存使用相关 RemoteImageType 的关联值作为键。 您可以通过以下方式自定义它:

RemoteImageService.cacheKeyProvider = { remoteImageType -> AnyObject in
    // return a key here
}

从 0.1.0 -> 1.0.0 的迁移

url parameter 已重构为 type parameter,这使得获取 URL 或 iCloud 中的图像变得容易。

变更

# Version 0.1.0
let url = URL(string: "https://images.unsplash.com/photo-1524419986249-348e8fa6ad4a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80")!

RemoteImage(url: url, errorView: { error in
    Text(error.localizedDescription)
}, imageView: { image in
    image
    .resizable()
    .aspectRatio(contentMode: .fit)
}, loadingView: {
    Text("Loading ...")
})

# Version 1.0.0
let url = URL(string: "https://images.unsplash.com/photo-1524419986249-348e8fa6ad4a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80")!

RemoteImage(type: .url(url), errorView: { error in
    Text(error.localizedDescription)
}, imageView: { image in
    image
    .resizable()
    .aspectRatio(contentMode: .fit)
}, loadingView: {
    Text("Loading ...")
})