Common tasks related to the ImageDownloader in Kingfisher.
ImageDownloader wraps a URLSession for downloading an image from the Internet. Similar to ImageCache, there
is a ImageDownloader/default downloader for downloading tasks.
Typically, you might use Kingfisher's view extension methods or KingfisherManager for image retrieval. These methods
prioritize searching the cache to avoid unnecessary downloads. If you need to download an image without caching it,
consider the following approach:
let downloader = ImageDownloader.default
downloader.downloadImage(with: url) { result in
switch result {
case .success(let value):
print(value.image)
case .failure(let error):
print(error)
}
}
When managing access to your image resources with permission controls, you can customize the request using a
KingfisherOptionsInfoItem/requestModifier(_:):
let modifier = AnyModifier { request in
var r = request
r.setValue("abc", forHTTPHeaderField: "Access-Token")
return r
}
downloader.downloadImage(with: url, options: [.requestModifier(modifier)]) {
result in
// ...
}
// This option also works for view extension methods.
imageView.kf.setImage(with: url, options: [.requestModifier(modifier)])
If an asynchronous operation is required before modifying the request, create a type that conforms to
AsyncImageDownloadRequestModifier:
class AsyncModifier: AsyncImageDownloadRequestModifier {
var onDownloadTaskStarted: ((DownloadTask?) -> Void)?
func modified(for request: URLRequest, reportModified: @escaping (URLRequest?) -> Void) {
var r = request
someAsyncOperation { result in
r.someProperty = result.property
reportModified(r)
}
}
}
Similarly, use the KingfisherOptionsInfoItem/requestModifier(_:) to apply this modifier. In such scenarios, the
KingfisherWrapper/setImage(with:placeholder:options:progressBlock:completionHandler:)-2uid3 or
ImageDownloader/downloadImage(with:options:completionHandler:)-5x6sa method will no longer return a DownloadTask
directly, as the download task isn't initiated instantly. To reference the task, monitor the
AsyncImageDownloadRequestModifier/onDownloadTaskStarted callback.
let modifier = AsyncModifier()
modifier.onDownloadTaskStarted = { task in
if let task = task {
print("A download task started: \(task)")
}
}
let nilTask = imageView.kf.setImage(with: url, options: [.requestModifier(modifier)])
Once the download has started, a DownloadTask will be created and returned. This can be used to cancel an ongoing
download task.
let task = downloader.downloadImage(with: url) { result in
// ...
case .failure(let error):
print(error.isTaskCancelled) // true
}
}
// After some time, but before the download task completes.
task?.cancel()
If you call DownloadTask/cancel() after the task has already finished, no action will be taken.
Likewise, the view extension methods return a DownloadTask as well. This allows you to store the task and cancel it
if needed:
let task = imageView.kf.set(with: url)
task?.cancel()
Alternatively, you can invoke KingfisherWrapper/cancelDownloadTask()-2gg15 on the image view to cancel the
current downloading task.
let task1 = imageView.kf.set(with: url1)
let task2 = imageView.kf.set(with: url2)
imageView.kf.cancelDownloadTask()
// `task2` will be cancelled, but `task1` is still running.
// However, the downloaded image for `task1` will not be set because the image view expects a result from `url2`.
NSURLCredentialThe ImageDownloader defaults to .performDefaultHandling upon receiving a server challenge. To supply custom
credentials, configure an ImageDownloader/authenticationChallengeResponder:
// In ViewController
ImageDownloader.default.authenticationChallengeResponder = self
extension ViewController: AuthenticationChallengeResponsable {
var disposition: URLSession.AuthChallengeDisposition { /* */ }
let credential: URLCredential? { /* */ }
func downloader(
_ downloader: ImageDownloader,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
{
// Provide your `AuthChallengeDisposition` and `URLCredential`
completionHandler(disposition, credential)
}
func downloader(
_ downloader: ImageDownloader,
task: URLSessionTask,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
{
// Provide your `AuthChallengeDisposition` and `URLCredential`
completionHandler(disposition, credential)
}
}
The default download timeout for a request is 15 seconds. To customize this for the downloader:
// Set the timeout to 1 minute.
downloader.downloadTimeout = 60
For setting a timeout specific to a request, utilize a KingfisherOptionsInfoItem/requestModifier(_:):
let modifier = AnyModifier { request in
var r = request
r.timeoutInterval = 60
return r
}
downloader.downloadImage(with: url, options: [.requestModifier(modifier)])