Networks are inherently unreliable. I use Kingfisher in SwiftUI to download a bunch of large images and I often experience failures, especially when using hotspot with 4G. It would be nice if Kingfisher could retry such errors. I'm actually surprised this is not already built into Kingfisher, as retrying is such a core feature when dealing with networks.
I imagine it would have some sane defaults, like 3 retries with exponential back-off, but be configurable if needed. I think it should retry on .invalidHTTPStatusCode, and also .URLSessionError if the error is (error as NSError).code == NSURLErrorTimedOut.
N/A
In https://github.com/onevcat/Kingfisher/issues/1058 you commented that you would be willing to look at this after Kingfisher 5.
You also argued:
For me, since I always use Kingfisher in a table view or collection view, every time the cell be loaded, it will try to load the image. More or less, it behaves like a "retry" for downloading images.
But this is not the case when used in SwiftUI.
Yes. A better retry mechanism is necessary, especially for the case in SwiftUI.
Before we can develop it, there is a bold "workaround" if you'd like to try, to use the alternativeSources option to download again when a failure happens:
extension KingfisherWrapper where Base: UIImageView {
func setImageWithRetryThreeTimes(url: URL) {
let source = Source.network(url)
setImage(with: source, options: [.alternativeSources([source, source, source])])
}
}
I'm already using a similar workaround, although not as clever.
The retry mechanism is already implemented in #1447 and it will be released soon.
To retry an image setting, pass a .retryStrategy option with an associated RetryStrategy value. Kingfisher provides a built-in DelayRetryStrategy with several parameters, like:
let retry = DelayRetryStrategy(maxRetryCount: 5, retryInterval: .seconds(3))
imageView.kf.setImage(with: imageURL, options: [.retryStrategy(retry)])
It will retry 5 times if there is something wrong in network, with a 3 seconds interval between each retry operation. You can also choose an .accumulated(3) way to have a 3 -> 6 -> 9 -> 12 -> 15 retry interval, or even define your own interval pattern by .custom.
If you need more control for the retry strategy, implement your own type conforming the RetryStrategy protocol and provide it as an option.
Released with version 5.14.0.
Released with version 5.14.0.
Thank you. Didn't know it is here now. Saved a lot of time.
Most helpful comment
The retry mechanism is already implemented in #1447 and it will be released soon.
To retry an image setting, pass a
.retryStrategyoption with an associatedRetryStrategyvalue. Kingfisher provides a built-inDelayRetryStrategywith several parameters, like:It will retry 5 times if there is something wrong in network, with a 3 seconds interval between each retry operation. You can also choose an
.accumulated(3)way to have a3 -> 6 -> 9 -> 12 -> 15retry interval, or even define your own interval pattern by.custom.If you need more control for the retry strategy, implement your own type conforming the
RetryStrategyprotocol and provide it as an option.