PreviewProviderは、Xcode Canvasでプレビューを生成するためのエントリポイントを定義するSwiftUIプロトコルです。プロトコルを実装することで、開発者はシミュレーターを起動せずにインターフェースを確認でき、レイアウト段階での反復を高速化します。Apple Developer Documentation(2026年)によると、プロジェクトがCanvasを使用する場合、PreviewProviderはすべてのSwiftUI Viewに必須であり、これがないとCanvasはユーザーインターフェースを表示しません。詳細はSwiftUIに関する記事をご覧ください。
主要ポイント
PreviewProviderは、Xcode Canvasでプレビューコンテンツを作成するための契約を定義するSwiftUIプロトコルです。プロトコルには必須プロパティが1つあります:previews(型はsome View)。previewsが返す値はすべて、Canvasに対話型プレビューとして表示されます。PreviewProviderは継承を必要としません — extensionでの静的実装で十分です。
アーキテクチャ的には、PreviewProviderはSwiftUIランタイムの一部ではなく、純粋に開発ツールです。プロトコルには@available(iOS 13.0, *)属性が付けられており、Xcodeが条件付きコンパイルを使用してプレビューコードを本番環境から除外するため、リリースビルドではコンパイルされません。つまり、PreviewProviderはバイナリサイズやアプリケーションのパフォーマンスに影響しません。
previewsプロパティはPreviewProviderの唯一の要件です。単純なTextからGroupやForEachを含む複雑な階層まで、任意のViewを返す必要があります。Xcodeは返されたViewをCanvasでレンダリングし、システム設定(テーマ、サイズ、フォント)を適用します。
import SwiftUI
struct GreetingView: View {
let name: String
var body: some View {
Text("Hello, \(name)!")
.padding()
}
}
// PreviewProvider — static implementation
struct GreetingView_Previews: PreviewProvider {
static var previews: some View {
GreetingView(name: "World")
}
}
命名規則:Appleはプレビュー構造体を{ViewName}_Previewsと命名することを推奨しています。これはコンパイラの要件ではありませんが、可読性とプロジェクトナビゲーションを向上させます。Xcodeは新しいSwiftUIファイルを作成する際に、自動的にこのテンプレートを挿入します。
動作メカニズム PreviewProviderは静的ディスパッチに基づいています。XcodeはDebug設定の場合のみPreviewProvider拡張をコンパイルし、Canvas構築プロセス中にpreviewsを呼び出します。コードが変更されるたびに、Xcodeは変更されたPreviewProviderのみを再コンパイルし、ほぼ瞬時のプレビュー更新を保証します。
SwiftUIは、シミュレーターやデバイス上のプレビューと最終的なUIの正確な一致を保証しません — Canvasは簡略化されたレンダリングを使用します。遅延のあるアニメーションは正しく表示されない場合があり、一部のUIKitコンポーネント(MapKit、WebView)は追加設定なしではCanvasでレンダリングされません。
Groupを使用すると、1つのViewの複数の状態を同時に表示でき、異なる設定をレイアウトする際の反復を高速化します。Group内の各プレビューは独立してレンダリングされます。
struct ButtonView_Previews: PreviewProvider {
static var previews: some View {
Group {
ButtonView(title: "Primary", style: .primary)
.previewDisplayName("Primary")
ButtonView(title: "Disabled", style: .primary)
.disabled(true)
.previewDisplayName("Disabled")
ButtonView(title: "Secondary", style: .secondary)
.previewDisplayName("Secondary")
}
}
}
previewDisplayNameはCanvasの各プレビューにラベルを追加します。これは複数の状態を比較する際に特に便利です。Group内のプレビュー数の上限はありませんが、6~8を超えるとCanvasが遅くなります。
Xcodeはプレビュー表示を設定するためのいくつかのモディファイアを提供しています。主なもの:previewDevice — 特定のデバイスをエミュレート(iPhone 16 Pro、iPad Air、Apple Watch Ultra)、previewLayout — サイズを設定(device、fixed、sizeThatFits)。これらのモディファイアの組み合わせにより、プレビュー環境を完全に制御できます。
previewDeviceはデバイス名の文字列を受け入れます。例:「iPhone 16 Pro」や「iPad Pro 13-inch (M4)」。利用可能なデバイスのリストはXcodeにインストールされたシミュレーターに依存します。デバイスが見つからない場合、Canvasはエラーなしでデフォルトデバイスにプレビューを表示します。
| モディファイア | 説明 | 例 |
|---|---|---|
| previewDevice | デバイスのエミュレーション | .previewDevice("iPhone 16 Pro") |
| previewLayout | サイズモード | .previewLayout(.sizeThatFits) |
| previewDisplayName | プレビューラベル | .previewDisplayName("Dark Mode") |
| preferredColorScheme | カラースキーム | .preferredColorScheme(.dark) |
| dynamicTypeSize | フォントサイズ | .dynamicTypeSize(.xxxLarge) |
一般的な慣行として、適応性を確認するために1つのViewを複数のデバイスで同時に表示します。これにはデバイス名の配列を持つForEachを使用します。
struct AdaptiveView_Previews: PreviewProvider {
static var previews: some View {
ForEach(["iPhone SE (3rd generation)", "iPhone 16 Pro Max", "iPad Pro 13-inch (M4)"], id: \.self) { device in
AdaptiveView()
.previewDevice(.previewDevice(device))
.previewDisplayName(device)
}
}
}
実践的な例は、単純なプレビューからライブデータやUIKit互換性を伴う複雑な設定まで、PreviewProviderのさまざまな使用シナリオを示しています。
モックデータは、Viewがモデルを受け入れる場合のプレビューの標準パターンです。実際のAPIの代わりにテストデータが使用され、アプリケーションを起動せずにUI状態を視覚的に確認できます。
struct UserProfileView: View {
let user: User
var body: some View {
VStack {
AsyncImage(url: user.avatarURL)
.clipShape(Circle())
Text(user.name)
.font(.title)
Text(user.bio)
.font(.body)
.foregroundColor(.secondary)
}
}
}
struct UserProfileView_Previews: PreviewProvider {
static var previews: some View {
UserProfileView(user: .mock)
.previewDisplayName("Profile")
UserProfileView(user: .mockLongName)
.previewDisplayName("Long Name")
}
}
UIKit互換性 — PreviewProviderはUIViewRepresentableでラップされたUIKitコンポーネントでも動作します。これにより、プロジェクト全体を移行することなく、既存のUIKitビューをSwiftUI Canvasでプレビューできます。
struct MapViewRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
MKMapView()
}
func updateUIView(_ uiView: MKMapView, context: Context) {
// Configure map
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapViewRepresentable()
}
}
CanvasはXcodeのビジュアルエディタで、PreviewProviderの出力をリアルタイムでレンダリングします。PreviewProviderの実装がないと、Canvasは空のままです。CanvasとPreviewProviderはペアで機能します。PreviewProviderが表示内容を定義し、Canvasが表示場所と方法を定義します。
重要なのは、Canvasはプレビュー実行環境であり、PreviewProviderの代替ではないということです。開発者がCanvasを開かなくても、PreviewProviderはCanvasアイコンにホバーした際のポップアッププレビューを通じて、迅速なコード確認に使用できます。WWDC 2024によると、Appleはユニットテストの作成と同様に、すべてのViewにPreviewProviderを書くことを開発標準として推奨しています。
| コンポーネント | 役割 | 必須 |
|---|---|---|
| PreviewProvider | プレビューコンテンツを定義 | Canvasに必須 |
| Canvas | エディタでプレビューをレンダリング | オプション(.previewを使用可) |
| SwiftUI View | UIコンポーネント | 必須 |
推奨事項:プロジェクトのすべての公開ViewにPreviewProviderを記述してください。これにより、新しい開発者のオンボーディングが促進され、コードレビューが簡素化され、プロジェクト全体をビルドせずに視覚的な変更を迅速に確認できます。
問題1:プレビューが更新されない。Canvasがコード変更を反映しない場合、原因は通常DerivedDataキャッシュです。Product → Clean Build Folder(⇧⌘K)からDerivedDataをクリアするか、~/Library/Developer/Xcode/DerivedDataフォルダを手動で削除してください。クリア後、Canvasはプレビューを最初から再構築します。
問題2:PreviewProviderが@StateObjectを認識しない。PreviewProviderはViewの静的インスタンスを作成するため、注入が必要な依存関係(ViewModel、サービス)はイニシャライザまたはデフォルト値を持つ@StateObjectを介して渡す必要があります。プレビューでは実際のサービスの代わりにモックオブジェクトを使用してください。
問題3:Canvasでアニメーションが動作しない。CanvasはすべてのSwiftUIアニメーションをサポートしているわけではありません — 特にタイミングに依存するもの(遅延付きのwithAnimation、.spring)が対象です。アニメーションのテストには、シミュレーターでアプリケーションを実行してください。Canvasは静的なレイアウト検証に適しています。
依存性注入は、複雑なViewModelでPreviewProviderを機能させる最良の方法です。テストデータを持つ別のViewModelインスタンスを作成し、Viewのイニシャライザに渡します。
struct DashboardView: View {
@StateObject var viewModel: DashboardViewModel
var body: some View {
List(viewModel.items) { item in
Text(item.title)
}
}
}
struct DashboardView_Previews: PreviewProvider {
static var previews: some View {
DashboardView(viewModel: DashboardViewModel.mock)
}
}
モック拡張:ViewModelの拡張を作成し、静的な.mockインスタンスを提供します。これにより、テストデータをViewModelの近くに保ち、PreviewProviderを読みやすくします。
よくある質問
技術的には不要です — PreviewProviderがなくてもアプリケーションはコンパイルされます。しかし実際には、AppleとSwiftUIコミュニティはすべての公開Viewにプレビューを書くことを推奨しています。PreviewProviderは開発を加速し、異なるデバイスでのレイアウトを迅速に確認でき、チームの視覚的なドキュメントとして機能します。
PreviewProviderはDebugビルドでのみコードを追加するため、プレビューがリリース設定で利用できない型を使用するとコンパイルエラーが発生する可能性があります。Canvasをサポートしないプラットフォームで@availableを使用する場合や、プレビューの複雑さの制限を超えた場合にもエラーが発生します。
直接は不可能です — PreviewProviderは隔離されて実行されます。モックデータを使用してください:.mockインスタンスを持つ静的モデル拡張を作成します。@StateObjectを使用するViewの場合は、イニシャライザを介してテストデータを持つViewModelを渡します。これにより、ネットワークリクエストなしで実際のデータをシミュレートします。
いいえ、PreviewProviderはリリースバイナリサイズに影響しません。Xcodeは条件付きコンパイル(#if DEBUG / #if !RELEASE)を使用して、リリースビルドからプレビューコードを除外します。PreviewProviderコードはDebug設定でのみ存在し、App Storeビルドには含まれません。
はい、Xcodeはプレビューデバッグをサポートしています。previewsまたはViewコード内にブレークポイントを設定し、Product → Preview → Debug Previewを選択します。Canvasレンダリング中にブレークポイントがトリガーされます。これはプレビューでのみ表示されるレイアウト問題の分析に役立ちます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。