mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Don't crash when the GIF data provider is invoked off the main thread
LoadableImageContent.data(handler:) used MainActor.assumeIsolated to read the loader's content, which crashes (libdispatch precondition) when Kingfisher invokes the provider off the main thread, and fatalError'd when the content wasn't GIF data. Hop onto the main actor and return a failure instead. The handler is @Sendable per Kingfisher's protocol.
This commit is contained in:
@@ -234,23 +234,24 @@ private struct LoadableImageContent<TransformerView: View, PlaceholderView: View
|
||||
mediaSource.url.absoluteString
|
||||
}
|
||||
|
||||
nonisolated func data(handler: @escaping (Result<Data, Error>) -> Void) {
|
||||
// Kingfisher isn't annotated but invokes the provider on the main thread.
|
||||
let gifData = MainActor.assumeIsolated { () -> Data? in
|
||||
nonisolated func data(handler: @escaping @Sendable (Result<Data, Error>) -> Void) {
|
||||
// Kingfisher isn't annotated and doesn't guarantee the provider is invoked on the main
|
||||
// thread so hop onto the main actor.
|
||||
Task { @MainActor in
|
||||
guard case let .gifData(data) = contentLoader.content else {
|
||||
return nil
|
||||
handler(.failure(LoadableImageError.missingGIFData))
|
||||
return
|
||||
}
|
||||
return data
|
||||
|
||||
handler(.success(data))
|
||||
}
|
||||
|
||||
guard let gifData else {
|
||||
fatalError("Shouldn't reach this point without any gif data")
|
||||
}
|
||||
|
||||
handler(.success(gifData))
|
||||
}
|
||||
}
|
||||
|
||||
private enum LoadableImageError: Error {
|
||||
case missingGIFData
|
||||
}
|
||||
|
||||
private class ContentLoader: ObservableObject {
|
||||
enum Content: Equatable {
|
||||
case image(UIImage)
|
||||
|
||||
Reference in New Issue
Block a user