PC パソコン

SwiftUI「Preview crashed」の原因と解決方法

SwiftUIのプレビューで「Preview crashed」と表示され、Canvasが落ちる・再読み込みを繰り返す場合は、View本体の実行時クラッシュだけでなく、Preview用データ、Environment依存、Swift Package、Simulator、DerivedData、Xcode Previews固有の不具合など複数の原因が考えられます。この記事では、原因の切り分けから代表的な解決方法まで順番に解説します。

「Preview crashed」が発生する主な原因

  • Preview内で強制アンラップや配列範囲外アクセスなどの実行時エラーが起きている
  • @Environment、@EnvironmentObject、SwiftData/Core Dataなど必要な依存関係がPreviewに渡されていない
  • Preview用のモックデータ作成時に例外やfatalErrorが発生している
  • Swift PackageやFrameworkのリンクに失敗している
  • Simulator RuntimeやPreview用Simulatorの状態が壊れている
  • DerivedDataやXcode Previewキャッシュが不整合を起こしている
  • Xcode側のPreview機能に一時的な不具合が発生している

代表的な発生状況

たとえば、通常のアプリ実行では問題がないのに、次のようなPreviewだけがクラッシュするケースがあります。

#Preview {
    ContentView()
        .environmentObject(AppModel())
}

一方、ContentView が別のEnvironment値や永続化コンテナを必要としているのにPreview側で渡していないと、Canvas起動時にクラッシュすることがあります。

最初に確認する手順

  1. 同じViewをSimulatorで通常実行してクラッシュするか確認する
  2. XcodeのCanvasに表示されるエラー詳細を開く
  3. Editor > Canvas > Diagnostics からPreview診断を確認する
  4. Preview用コードを最小構成にし、依存関係を1つずつ戻す
  5. Simulator一覧とRuntimeの状態を確認する

解決方法1:Previewコードを最小構成にする

まず、Previewに渡しているモックデータやEnvironment設定を外し、最小構成で表示できるか確認します。

#Preview {
    ContentView()
}

これで表示できる場合は、Previewに追加していた依存関係のどれかが原因です。

解決方法2:EnvironmentObjectなど必要な依存関係を渡す

@EnvironmentObject を使用しているViewでは、Preview側でも対応するオブジェクトを注入します。

#Preview {
    ContentView()
        .environmentObject(AppModel())
}

SwiftDataを使用している場合は、Preview専用のインメモリModelContainerを用意すると、本番データに依存せず安全に確認できます。

#Preview {
    let config = ModelConfiguration(isStoredInMemoryOnly: true)
    let container = try! ModelContainer(for: Item.self, configurations: config)
    return ContentView().modelContainer(container)
}

解決方法3:Preview内の実行時クラッシュを確認する

Previewも実際にコードを実行するため、強制アンラップや配列範囲外アクセスがあるとCanvasだけが落ちることがあります。

let value = optionalValue!
let first = items[0]

Preview用データが空やnilになる可能性を確認し、安全なアクセスへ変更します。

if let value = optionalValue { Text(value) }
if let first = items.first { Text(first.title) }

解決方法4:Canvasを再起動する

コードに問題がなくてもPreviewプロセスだけが不安定になることがあります。CanvasのRestartボタンを押すか、Canvasを閉じて再度表示します。

Appleの現在のXcodeドキュメントでも、Canvasが停止している場合はRestartでPreviewを再実行できると案内されています。

解決方法5:DerivedDataを削除する

古いビルド成果物やPreview用キャッシュが原因の場合は、DerivedDataを削除して再ビルドします。

rm -rf ~/Library/Developer/Xcode/DerivedData/*

削除後にXcodeを再起動し、プロジェクトをBuildしてからPreviewを再表示します。

解決方法6:Simulatorの状態を確認する

PreviewはSimulator Runtimeを利用するため、Simulatorが壊れているとPreviewもクラッシュすることがあります。

xcrun simctl list devices
xcrun simctl list runtimes

利用不能なデバイスだけを整理する場合は次を使えます。

xcrun simctl delete unavailable

解決方法7:Swift PackageやFrameworkを確認する

Preview診断に「Runtime linking failure」「Symbols not found」などが出る場合は、依存ライブラリのリンクが原因です。Package Dependenciesを再解決し、対象PackageがPreview対象のプラットフォーム・アーキテクチャに対応しているか確認します。

xcodebuild -resolvePackageDependencies

解決方法8:Preview専用処理を見直す

ネットワーク通信、Keychain、ファイルアクセス、外部サービス初期化などをViewの初期化時に直接実行すると、Preview環境では失敗することがあります。Previewでは固定のモックデータを渡し、外部I/Oを避ける構成にすると安定します。

それでも直らない場合

最小構成のViewでもPreviewがクラッシュする場合はXcode側の問題も疑います。Xcodeを再起動し、XcodeとSimulator Runtimeを最新の安定版へ更新します。それでも再現する場合は、Editor > Canvas > Diagnostics から診断レポートを生成し、AppleへのFeedbackに添付します。

Previewのクラッシュは、アプリ本体のビルド成功とは別に発生します。「アプリはSimulatorで動くがPreviewだけ落ちる」場合は、Preview固有の依存関係・Simulator・Runtime Linking・Xcode側の不具合を優先して確認してください。

まとめ

SwiftUIの「Preview crashed」は、View内部の実行時エラー、Environment不足、Preview用データ、依存Package、Simulator、DerivedDataなどが主な原因です。まずPreviewを最小構成にし、Diagnosticsでクラッシュ箇所を確認してください。その後、Environmentやモックデータ、Simulator、Package依存を順番に戻していくと原因を特定しやすくなります。