Swift

Swift Concurrency入門:async/awaitとthrowsの使い方とエラーハンドリング

ⓘ本ページはプロモーションが含まれています

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


スポンサードリンク

Swift Concurrency の基礎 ― async / awaitthrows のシグネチャ

結論

  • asyncthrows は同時に宣言できる。
  • これにより 非同期処理で発生するエラー をコンパイル時に安全に扱えるようになる。

背景と理由

項目 説明
async 関数が非同期であることを示し、呼び出し側は必ず await で待機する必要がある。実行は別スレッド(もしくは同一スレッドの協調的切り替え)で行われる。
throws エラー発生時に例外を throw でき、呼び出し側は必ず trydo‑catch によってハンドリングすることが強制される。
両方併用 async throws と書くことで「非同期かつ失敗可能」な API を宣言でき、型システムが 成功・失敗の両方 を保証してくれる。

Swift 5.5 以降はこの組み合わせが標準となり、従来のコールバックや Result 型に比べてコードが圧倒的にシンプルになる。


非同期関数の基本例

  • 呼び出し側は必ず try await と書く
    swift
    let user = try await fetchUser(id: "123")

do‑catchtry / try? / try! の使い分け

結論

キーワード 挙動 推奨シーン
try エラーが発生すると 捕捉必須。コンパイルエラーになるため、失敗を必ず処理できる。 UI にエラーメッセージを表示したいとき、リトライロジックを入れたいとき
try? エラーは nil へ変換され、結果はオプショナルになる。失敗時に何もしないケースで有用。 キャッシュが無くても処理を続行できる場合
try! エラーが起きたら ランタイムクラッシュ。デバッグ以外では使用しないこと。 テストコードや、絶対に失敗し得ないと確信できる内部ロジック

実装例

ベストプラクティス

  1. UI 更新は必ず MainActor.run / DispatchQueue.main.async
  2. エラーログは一元化(例: os_log + Crashlytics)
  3. do‑catch の中でエラー型を絞り込むと、適切なユーザー通知が書きやすくなる。

Task, withThrowingTaskGroup, async let におけるエラーハンドリング

結論

構文 主な用途 エラー伝搬の特徴
Task {} 単一非同期処理をバックグラウンドで走らせる await task.value で取得。内部エラーは自動的にキャンセルされ、呼び出し側で捕捉できる
withThrowingTaskGroup 複数タスクを同時実行しつつ、最初の失敗で全体をキャンセルしたいケース 各タスクは個別に throw 可能。グループ外へは 最初にスローされたエラー が伝搬
async let 軽量な並列実行(数個程度) await (a, b) の時点で全タスクの結果が集約され、いずれかが失敗すればその場で例外が発生

実装サンプル

ポイントまとめ

  • Task は「非同期で実行したいが結果をすぐに待ちたくない」場合に使用。
  • withThrowingTaskGroup は「多数タスクを同時走査し、失敗時は全体を止めたい」シナリオのデファクトスタンダード。
  • async let は数個程度の軽量並列処理に最適だが、エラーは await 時点でまとめて捕捉する必要がある。

キャンセルエラーと通常エラーの分離、Result 型+Continuation の併用例

結論

  • CancellationError は特別扱いし、ログに残すかどうかはケースバイケースで決定する(多くは無視して再スロー)。
  • Result + withCheckedThrowingContinuation により、コールバックベースの API でも型安全な async/await 呼び出しが実現できる。

実装例

補足ポイント

  • CancellationErrorユーザー操作やシステムポリシー による中断が目的なので、通常ログに残すとノイズが増えることが多い。
  • Continuation 系 API は メモリリークの危険性 があるため、必ず resume を 1 回だけ呼び出すように注意する。

実務で推奨されるエラーロギング・ユーザー通知パターン

結論

  • エラーは 「ロギング層」「ユーザー向けフィードバック」 に分離して処理すべき。
  • これによりデバッグ情報の取得が容易になると同時に、UX が損なわれない。

実装例(UIKit 前提)

パターンの要点

項目 実装ポイント
ロギングは一元化 os.Logger(iOS 14+)+外部サービス(例: Crashlytics)で全エラーを集約。
エラー種別ごとの UI フロー - CancellationError → 静かに無視
- ネットワーク障害 → 「リトライ」ボタン付きアラート
- パース失敗などの致命的エラー → 「閉じる」だけのシンプルな通知
共通ユーティリティ logErrorpresentErrorAlert をプロジェクト全体で共有し、コード重複を防止。

まとめ

  1. async throws が提供する安全性
  2. 非同期処理でもコンパイル時に失敗可能性が明示されるので、例外漏れが減少。

  3. エラーハンドリングの基本構造

  4. do‑catch → 必須
  5. try? は「結果を無視できる」ケースでのみ使用
  6. try! はデバッグ時以外は禁止

  7. タスク並列化とエラー伝搬

  8. 単一処理は Task {}、多数タスクは withThrowingTaskGroup、軽量な同時実行は async let

  9. キャンセルと通常エラーの分離

  10. CancellationError は必要に応じてログを省略しつつ再スロー。

  11. 既存コールバック API の橋渡し

  12. Result + withCheckedThrowingContinuation で安全に async/await に変換できる。

  13. 実務レベルのロギング・通知

  14. ログは一元化、ユーザー向けメッセージはエラー種別に合わせて適切な UI を提示する。

これらのベストプラクティスをプロジェクトに組み込めば、Swift Concurrency のエラーハンドリングが 安全かつ保守しやすく なり、開発者とユーザー双方にメリットをもたらします。

スポンサードリンク

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


-Swift