MeWrite Docs

Main Thread Checker: UI API called on a background thread

iOSでバックグラウンドスレッドからUIを更新しようとした場合に発生

概要

iOSでは、UIの更新は必ずメインスレッドで行う必要があります。バックグラウンドスレッドからUIを操作しようとすると、このエラーが発生します。

エラーメッセージ

Main Thread Checker: UI API called on a background thread: -[UILabel setText:]

原因

  1. 非同期処理のコールバック内でUI更新: completionハンドラ内でUI操作
  2. URLSessionのdataTask: デフォルトでバックグラウンドスレッドで実行
  3. Combine/RxSwiftのスレッド: 明示的にメインスレッドに切り替えていない

解決策

1. DispatchQueue.main.asyncを使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
URLSession.shared.dataTask(with: url) { data, response, error in
    // バックグラウンドスレッド
    let result = parseData(data)

    // UIの更新はメインスレッドで
    DispatchQueue.main.async {
        self.label.text = result
        self.tableView.reloadData()
    }
}.resume()

2. @MainActorを使用(Swift 5.5+)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@MainActor
class ViewController: UIViewController {
    func updateUI(with data: String) {
        label.text = data  // 自動的にメインスレッドで実行
    }
}

// または
Task { @MainActor in
    label.text = "Updated"
}

3. async/awaitでメインスレッドに戻る

1
2
3
4
5
6
7
func fetchAndDisplay() async {
    let data = await fetchData()  // バックグラウンド

    await MainActor.run {
        label.text = data  // メインスレッド
    }
}

4. Combineでreceive(on:)を使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
URLSession.shared.dataTaskPublisher(for: url)
    .map(\.data)
    .decode(type: Response.self, decoder: JSONDecoder())
    .receive(on: DispatchQueue.main)  // メインスレッドに切り替え
    .sink { completion in
        // エラー処理
    } receiveValue: { response in
        self.label.text = response.title  // OK
    }
    .store(in: &cancellables)

5. RxSwiftでobserve(on:)を使用

1
2
3
4
5
6
apiClient.fetchData()
    .observe(on: MainScheduler.instance)
    .subscribe(onNext: { data in
        self.label.text = data
    })
    .disposed(by: disposeBag)

6. ViewModelパターン

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class ViewModel: ObservableObject {
    @Published var text: String = ""

    func fetch() {
        Task {
            let result = await api.fetchData()
            await MainActor.run {
                self.text = result
            }
        }
    }
}

Swift の他のエラー

最終更新: 2025-12-09