SwiftUIのPublishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.の対処方法を説明する。
結論
DispatchQueue.main.async { }を使う。
具体例
URLをダウンロードするclassが有るとする。このclassのダウンロードはバックグラウンドスレッドで実行される。このclassが@Publishedの変数を持つとする。この変数の更新はメインスレッドで実行する必要がある。よってこの変数の更新はDispatchQueue.main.async { }を使う。
class ダウンローダーのモデル: NSObject, ObservableObject, URLSessionDownloadDelegate {
@Published var ダウンロード進捗: Float = 0
〜中略〜
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
DispatchQueue.main.async { // ? メインスレッドで実行する
self.ダウンロード進捗 = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
}
}
〜中略〜
}
仮にDispatchQueue.main.async { }を使わないとする。
class ダウンローダーのモデル: NSObject, ObservableObject, URLSessionDownloadDelegate {
@Published var ダウンロード進捗: Float = 0
〜中略〜
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
self.ダウンロード進捗 = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
}
〜中略〜
}
そうするとPublishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.が出る。
まとめ
SwiftUIのPublishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.の対処方法を説明した。
コメント