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.の対処方法

SwiftUI

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.の対処方法を説明した。

コメント

タイトルとURLをコピーしました