This Swift package provides a wrapper view around the existing SwiftUIImage view which adds support for showing and caching remote images.
In addition you can specify a loading and error view.
You can display images from a specific URL or from the iCloud (through a PHAsset identifier).
💡 Installation
Add this Swift package in Xcode using its Github repository url. (File > Swift Packages > Add Package Dependency…)
🧭 How to use
Just pass a remote image url or the local identifier of a PHAsset and ViewBuilders for the error, image and loading state to the initializer. That’s it 🎉
Clear the image cache through RemoteImageService.cache.removeAllObjects().
📖 Examples
The following code truly highlights the simplicity of this view:
URL example:
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 ...")
})
Under the hood the URLSession.shared is used by default as the RemoteImageURLDataPublisher to fetch the image at the specified URL.
You can specify a custom publisher through theremoteImageURLDataPublisher parameter.
As an example that’s how you could add support for low data mode to the RemoteImage view.
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 ...")
})
Custom RemoteImageService
If you want complete control over the service responsible for managing the state of the view and for fetching the image you could pass an object conforming to the RemoteImageService protocol to the related initializer:
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 ...")
})
In addition to that you could use the new @StateObject property wrapper introcuded in Swift by creating an instance of the default built-in RemoteImageService and using the above initializer:
@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 ...")
})
Custom cache
The RemoteImageService uses a default cache. To use a custom one just conform to the protocol RemoteImageCache and set it on the type RemoteImageService.
RemoteImageService.cache = yourCache
Custom cache key
The default cache uses the associated value of the related RemoteImageType as the key. You can customize this by setting a cache key provider through
RemoteImageService.cacheKeyProvider = { remoteImageType -> AnyObject in
// return a key here
}
Migration from 0.1.0 -> 1.0.0
The url parameter was refactored to a type parameter which makes it easy to fetch images at a URL or from the iCloud.
Change
# 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 ...")
})
to
# 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 ...")
})
RemoteImage
This Swift package provides a wrapper view around the existing SwiftUI
Image viewwhich adds support for showing and caching remote images. In addition you can specify a loading and error view.You can display images from a specific URL or from the iCloud (through a
PHAssetidentifier).💡 Installation
Add this Swift package in Xcode using its Github repository url. (File > Swift Packages > Add Package Dependency…)
🧭 How to use
Just pass a remote image url or the local identifier of a
PHAssetandViewBuilders for the error, image and loading state to the initializer. That’s it 🎉Clear the image cache through
RemoteImageService.cache.removeAllObjects().📖 Examples
The following code truly highlights the simplicity of this view:
URL example:
PHAsset example:
Custom
RemoteImageURLDataPublisherUnder the hood the
URLSession.sharedis used by default as theRemoteImageURLDataPublisherto fetch the image at the specified URL. You can specify a custom publisher through theremoteImageURLDataPublisherparameter. As an example that’s how you could add support for low data mode to theRemoteImageview.Custom
RemoteImageServiceIf you want complete control over the service responsible for managing the state of the view and for fetching the image you could pass an object conforming to the
RemoteImageServiceprotocol to the related initializer:In addition to that you could use the new
@StateObjectproperty wrapper introcuded in Swift by creating an instance of the default built-inRemoteImageServiceand using the above initializer:Custom cache
The
RemoteImageServiceuses a default cache. To use a custom one just conform to the protocolRemoteImageCacheand set it on the typeRemoteImageService.Custom cache key
The default cache uses the associated value of the related
RemoteImageTypeas the key. You can customize this by setting a cache key provider throughMigration from 0.1.0 -> 1.0.0
The
url parameterwas refactored to atype parameterwhich makes it easy to fetch images at a URL or from the iCloud.Change
to