技術コラムCOLUMN

SwiftUIの検索APIで古い結果を表示しないために:.task(id:)とSwift Concurrencyのキャンセル設計

  • iOS Development
  • 2026.10.19

SwiftUIの検索では、古いAPIレスポンスが遅れて届き、新しい結果を上書きすることがあります。

対策

.task(id: query)は検索語が変わると旧タスクをキャンセルします。ただしキャンセルは協調的です。レスポンスを画面に反映する直前にTask.checkCancellation()で確認し、UI状態を@MainActorで管理します。

コード例(iOS 17以降)

let (data, response) = try await URLSession.shared.data(from: url)
try Task.checkCancellation()

guard let http = response as? HTTPURLResponse,
      (200...299).contains(http.statusCode) else {
    return
}

let items = try JSONDecoder().decode([Article].self, from: data)
try Task.checkCancellation()
state = .loaded(items)

画面側は.task(id: query) { await model.search(query) }で起動します。実務では入力の間引き、キャンセル時のエラー抑止、レスポンス順序のテストも必要です。

参考資料

Apple公式:https://developer.apple.com/documentation/swift/task/

URLSession:https://developer.apple.com/documentation/foundation/urlsession/data%28from%3A%29

この記事を書いた人

Kaoru Miyamoto