View in English

  • Apple Developer
    • 今すぐ始める

    「今すぐ始める」を詳しく見る

    • 概要
    • 学ぶ
    • Apple Developer Program

    最新情報

    • 最新ニュース
    • Hello Developer
    • プラットフォーム

    プラットフォームを詳しく見る

    • Appleプラットフォーム
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    特集

    • デザイン
    • 配信
    • ゲーム
    • アクセサリ
    • Web
    • Home
    • CarPlay
    • テクノロジー

    テクノロジーを詳しく見る

    • 概要
    • Xcode
    • Swift
    • SwiftUI

    特集

    • アクセシビリティ
    • AIと機械学習
    • App Intent
    • Apple Intelligence
    • ゲーム
    • セキュリティ
    • Xcode Cloud
    • コミュニティ

    コミュニティを詳しく見る

    • 概要
    • 「Appleに相談」イベント
    • コミュニティイベント
    • デベロッパフォーラム
    • オープンソース

    特集

    • WWDC
    • Swift Student Challenge
    • デベロッパストーリー
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Center
    • ドキュメント

    ドキュメントを詳しく見る

    • ドキュメントライブラリ
    • テクノロジー概要
    • サンプルコード
    • ヒューマンインターフェイスガイドライン
    • ビデオ

    リリースノート

    • 注目のアップデート
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • ダウンロード

    ダウンロードを詳しく見る

    • すべてのダウンロード
    • オペレーティングシステム
    • アプリ
    • デザインリソース

    特集

    • Xcode
    • TestFlight
    • フォント
    • SF Symbols
    • Icon Composer
    • サポート

    サポートを詳しく見る

    • 概要
    • ヘルプガイド
    • デベロッパフォーラム
    • フィードバックアシスタント
    • お問い合わせ

    特集

    • アカウントヘルプ
    • App Reviewガイドライン
    • App Store Connectヘルプ
    • 近日導入予定の要件
    • 契約およびガイドライン
    • システムステータス
  • クイックリンク

    • イベント
    • ニュース
    • Forum
    • サンプルコード
    • ビデオ
 

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • すべてのビデオ
  • 利用方法
  • 概要
  • トランスクリプト
  • SwiftUIにおけるデータフロー

    SwiftUIでデータフローを管理するためのツールやテクニックを学びましょう。プロパティラッパーでデータをモデリングし、@Observableの機能を活用して、アプリに永続性を実装する方法をご確認ください。

    このセッションは、「Appleに相談」アクティビティである「SwiftUIの基礎:SwiftUIで優れたアプリを構築」の一部として実施されました。ビデオ全編を視聴して、詳しい情報や関連セッションをご確認ください。

    リソース

      • HDビデオ
      • SDビデオ
  • このビデオを検索

    皆様、こんにちは。私はコールと申します。 Appleのコアテクノロジー・ エバンジェリストを務めております。 本日は、アプリ内のデータと、そのデータを SwiftUIのビューにどのように 流していくかについてお話しいたします。 「Wish List」アプリは、 本日一日を通して、 SwiftUIアプリにおけるデータフローの 具体的な事例を解説する上で、 非常に優れた例となります。

    この「ウィッシュリスト」アプリは、 皆さんのアプリでも 必要となるようなデータ処理を数多く 行っており、対象となるデータの種類に 応じて異なるアプローチを採用しています。

    まずは、最も重要な点についていくつか ご説明いたします。 このアプリには、 ユーザーが操作を行った際に インターフェースの状態が 変化する箇所がいくつかあります。 例えば、ユーザーが 旅行プランを編集している際、 アプリはUIが編集モードにあるかどうかを 追跡する必要があります。

    このような状況は、 ボタンをタップした後にシートが 表示されるタイミングや、 アラートを表示する必要があるタイミングなど、 いくつかの場面で発生します。 私は、こうしたケースを総称して 「ビュー状態」と呼ぶことにします。

    また、このアプリにはデータモデルもあります。

    「ウィッシュリスト」アプリの目的は、 私の素晴らしい旅行やアクティビティに 関する豊富なデータをすべて表示することです。 例えば、この京都への旅行では、 お寺巡りや日の出の運河沿いの散歩など、 現地で楽しめる楽しいアクティビティが 数多く紹介されています。 そこで、このデータをアプリ内でモデル化し、 すべてのSwiftUIビューに 反映させる必要があります。

    また、アプリではユーザーが 設定した好みを追跡する必要があります。 例えば、アプリには 旅行のアクティビティ一覧に 並べ替えボタンがあります。 タイトルや日付、あるいは アクティビティの完了状況などで 並べ替えることができますが、 アプリはユーザーが最後に選択した 並べ替え方法を記憶し、次回このビューが 表示された際にも同じ並べ替え方法が 適用されるようにする必要があります。

    そして最後に、アプリを構築したい…… いえ、データ永続化のためのアプローチを 構築したいと考えています。 データ永続化とは、アプリが データをファイルなど、 デバイスのストレージに 保存できるようにする手法のことです。 そうすることで、ユーザーが 次にアプリに戻った際、 アプリを再起動した後であっても、 すべての変更内容がそのまま残っています。

    そこで、このセッションでは、 これらのユースケースについてそれぞれより 詳しく解説していきます。 これには、ビュー状態のデータ、 リッチなデータモデルの構築、 設定や構成の処理、そして永続化のためのいくつかの テクニックが含まれます。

    このセッションが終わる 頃には、これらのユースケースそれぞれについて 考察できるようになり、 ご自身のアプリで同様のニーズに対応するために 応用できるパターンも 理解できるようになるでしょう。 それではまず、ViewState から 始めましょう。

    先ほども触れましたが、 アプリによっては、インターフェース自体の 状態を追跡するために、 一部のデータを作成する 必要がある場合があります。 こうしたデータは 多くの場合一時的なものであり、 ビューが消えた際に リセットしても問題ありません。 例えば、サンプルアプリでは、 旅行プランが編集モードにあるかどうかを 追跡しています。 もしユーザーがこの旅行プランから 別の画面に移動し、 後で戻ってきた場合、 UIがもはや編集モードになっていないのは 理にかなっています。 たとえ「完了」をタップしていなかった としてもです。 インターフェース内で追跡する必要がある 状態の、もう一つの例をご紹介します。 このアプリの「ウィッシュリスト」タブには、 ツールバーに「追加」ボタンがあります。 さて、Kurtさんは先ほど、アニメーションの 微調整についてお話しされた際、 このボタンについて触れられました。 このボタンをタップするとシートが 表示され、ユーザーはアプリに 追加する新しい旅行の詳細を 入力できるようになります。

    したがって、アプリには、シートが現在画面に 表示されているかどうかを追跡するための 状態が必要です。

    また、シート自体にも、 変更を保存したり、旅行の追加をキャンセルしたりするための ボタンがあります。 そのため、シート内のこれらのアクションでは、 SwiftUIがシートを非表示にするよう、 状態を更新する仕組みが必要になります。

    では、ウィッシュリストビューの 本体にシートを配置し、 SwiftUIでこの「追加」

    ボタンを実装する方法をご紹介します。 シンボルラベルが付いた SwiftUIボタンがあり、 シートを表示するためのコードを ボタンのアクションに

    追加する必要があります。 ここで、ビューに追加される「isPresented」 修飾子を使用する必要があります。

    さて、このコードを完成させる前に、 SwiftUI では判断を 下す必要があります。 現在、このシートが実際に画面に 表示されているかどうかを追跡する データとは何でしょうか?

    これは、「at state」API を 使用するのに最適なユースケースです。 仕組みは次の通りです。 「isPresentingTrip」という 新しいプロパティを作成し、 ` atState` を使用して装飾します。

    デフォルト値は ` false` に設定します。 ` atState` を使用することで、 SwiftUI に、 このビューが存在する限り存続する 新しいデータを作成するよう指示します。 この値のライフタイムについては 後ほど詳しく説明しますが、 ひとまず定義が完了したので、 ビューの他の部分でこれを 使用できるようになりました。

    アクションボタンのアクションでは、 ボタンをタップすると常にシートが 表示されるようにするため、 ` isPresentingAddTrip` を` true` に 設定します。また、シートがすでに 表示されている場合は、この状態を` disabled` 修飾子に渡すことで、 ボタンを無効化します。

    なお、ビュー本体はこの修飾子内で` isPresentingAddTrip` の値を読み取ります。 ウィッシュリストビューは、 ` isPresentingAddTrip` の値が変更されるたびに、この値への依存関係を確立します。 ` isPresentingAddTrip` の値が変更されると、 SwiftUIはこのビューを更新します。 また、 `

    isPresentingAddTrip` プロパティを` sheet` 修飾子に渡します。 このドル記号の表記により、この状態への バインディングを渡すことができます。 このコードがシートとこの値を 共有できるようにすることで、 シートは値を読み取ることも 変更を加えることも可能になります。 バインディングについては、後ほど 詳しく説明します。

    プロパティに ` at` を付加することで、 SwiftUI にこのプロパティが 囲んでいるビューに 所有されていることを伝えます。

    このプロパティの値は、 ビューが存在する限り存在し続けます。

    これは先ほど少し触れた重要なポイントです。 状態プロパティは、ビュー構造体自体の ライフタイムではなく、 インターフェースにおけるビューの ライフタイムに一致します。 そこで、これが実際にどのように 機能するのかについて、 さらに詳しく掘り下げていきます。 本日、Leahさんがお話ししたように、 SwiftUIのビューはテンプレートのように、 短命な記述に過ぎません。 ウィッシュリストのビューがインターフェースに 表示されると、SwiftUIはその 本体を実行して 画面上のUIを更新しますが、

    その後そのインスタンスを破棄します。

    この処理は、SwiftUIがビューを レンダリングするたびに繰り返されます。 では、デフォルト値がfalseであるにもかかわらず、このビューが再初期化されるたびに、 ` isPresenting` と` addTrip` プロパティがリセットされないのはなぜでしょうか? それは、SwiftUIがこのような 状態プロパティに 対して特別な処理を行っているためです。

    裏側では、SwiftUIは ビューが所有するすべての状態を 格納するための独自のデータストレージを 持っています。 SwiftUIがこのビューを初めて インスタンス化する際、 他のビューが所有するすべての状態と共に、 このプロパティのためのスペースを 内部ストレージに割り当てます。

    このストレージは、ビューのIDによって インデックス付けされています。

    この識別子は、画面上に レンダリングされたこのビューの結果の存続期間に 対応するものと考えてください。 つまり、SwiftUI が 初めてこのビューをレンダリングする際、 そのビューに識別子を割り当てます。

    そして、ユーザーがこのビューから別のビューへ 移動すると、SwiftUI はその ストレージからエントリを削除します。 後で再びこのビューに戻ってきた場合、 SwiftUI は新しい識別子を割り当て、 ストレージ内に新しいエントリを割り当てます。

    では、ウィッシュリストビューに初めて 移動した際に、タップするとシートを表示する 私のボタンが、どのように 動作するかをご説明いたします。 SwiftUIは、 このビューのためにストレージを割り 当てます。

    このビューは、デフォルト値がfalseの` presentingAddTripState` プロパティを使用しています。 その後、構造体をインスタンス化し、 ` presenting` の値を設定します。 ` presenting` は、 SwiftUIの内部ストレージに合わせて 「presentingAddTrip」の プロパティをtrueに設定し、 ウィッシュリストビューのボディを実行して 画面にレンダリングします。 その後、アプリの利用者が ボタンをタップすると、 ビューのインスタンスは破棄されます。 アクションクロージャーが実行され、 「presentingAddTrip」 のプロパティがtrueに設定されますが、 これは状態プロパティであるため、 この代入によって SwiftUIの内部ストレージが変更されます。 また、ビューのボディはこの状態に 依存しているため、SwiftUIは 更新をトリガーします。 新しいビュー構造体を作成し、内部ストレージから 取得した新しい「true」の値で ` isPresentingAddTrip` の値を設定します。 ` body` を実行する前です。 つまり、この内部ストレージこそが、 SwiftUI が インターフェース内のビューの存続期間を通じて 状態を維持する仕組みなのです。 構造体自体は一時的なものであってもです。

    さて、この内部ストレージによって、 この ` at state` プロパティが、 インターフェース内のこのビューの存続期間中、 SwiftUI にブール値を追跡するよう 指示している仕組みが説明できます。 しかし、 ` at state` は 単一のビュー宣言内だけで 役立つわけではありません。 「バインディング」と呼ばれる機能を使用して、 他のビューと共有することも可能です。

    このシートモディファイアにある ドル記号($)により、 バインディングにアクセスできます。 こちらは「旅行の追加」状態を表示しています。

    バインディングとは、アプリ内の特定の状態に 対する読み書き可能な参照のことです。

    バインディングは、親ビューから値を読み取る 必要があり、場合によってはその値を変更する 必要もあるビューを作成する 際に非常に役立ちます。

    バインディングはSwiftUIの至る 所で使用されています。 トグルやテキストフィールド、 シート修飾子のパラメータなど、 さまざまな場所で確認できます。

    これらは、このデータに依存し、必要に 応じてデータを変更できるカプセル化された コントロールです。 例えば、こちらが「旅行の追加」 ビューのスニペットです。 これは、シート内部にあるビューそのものです。

    このビューでは、バインディングを 使用して、親ビューから、 シートがビュー本体に 表示されているかどうかを追跡する 状態への参照を受け取っています。 シートを閉じるためのボタンがあります。 これを行うために、これらのボタンは アクションクロージャ内で 「Ispresented」 バインディングの値をfalseに設定します。 これにより、SwiftUI は 私のビューのように、その状態に 依存するすべてのビューを更新します。 ビューを閉じると、シートが非表示になります。

    私のシートのように、ユーザーが インターフェースとインタラクションした タイミングを追跡したいだけの 場所には、at stateは、 ビューが消えたときに リセットされるべき一時的なデータや、 ビューが存在している間のみ 存在すべきオブジェクトがある場合に最適です。

    しかし、at stateは、 私のデータモデルのような他の種類の データには最適ではありません。 そのようなケースでは、UI自体ではなく、 コードの他の部分が所有する 状態の種類をSwiftUIに 表現する方法が必要になります。

    そこで、次のユースケースとして、 ウィッシュリストのデータモデルについて お話しします。 このデータモデルは、このアプリの 心臓部であり、魂そのものです。 ここには、各旅行の名称や写真、 アクティビティなど、ユーザーがアプリに 繰り返しアクセスしたくなるような 情報がすべて含まれています。 この例のように、 「Peru off Road」 という名前の旅行オブジェクトには、 この素晴らしい写真が関連付けられています。

    また、これらのオブジェクト間には 関係性もあります。 例えば、1つの旅行には 複数のアクティビティが含まれることがあり、 アクティビティには名前や、アクティビティが 完了したかどうかを追跡するためのブール値といった 独自の属性があります。

    そこで、このアプリ内の旅行や アクティビティを表すために、 クラスを使用したデータモデルを作成しました。 各クラスには、名前、写真、日付などの属性を 格納するためのプロパティがあります。

    また、これらのオブジェクト間の 関係をモデル化するために、 相互への参照も格納されています。 例えば、旅行オブジェクトは、 activitiesプロパティにアクティビティへの 参照を格納することで、 任意の数のアクティビティを 関連付けることができます。

    また、ユーザーがUI上でこれらの プロパティを変更する 可能性があるため、これらの オブジェクトは編集可能です。 たとえば、テキストフィールドで 旅行の名前を編集する場合などが挙げられます。

    また、アプリ内のこれらすべての オブジェクトを管理するために、 「DataSource」という クラスも作成しました。 これは、アプリが UI に表示するために 必要なすべてのオブジェクト(例えば、 すべての旅行のリストなど) を一元的に取得できる場所です。

    このようにデータモデルを用意することは、 素晴らしい第一歩です。 しかし、このデータモデルを SwiftUI で実際に活用するには、 もう一つ簡単な追加が必要です。

    SwiftUIがUIを更新できるように、 データモデルはプロパティの変更が 発生したことを認識できる必要があります。

    そこで役立つのが、 ` observable` マクロです。 この1行のコードを追加するだけで、 SwiftUIがクラスのプロパティに 対する依存関係を 確立できるようになります。

    ` observable` マクロは、 各クラスのプロパティに 更新追跡機能を追加します。 これを使用するには、 各クラスに ` at observable` マクロを適用するだけです。

    これでデータモデルがオブザーバブルになった ため、 SwiftUIはモデルのプロパティに 対して直接依存関係を 確立できるようになりました。

    この例では、 ` tripcard` ビューは、表示すべき ` trip` オブジェクトへの 参照を受け取ります。

    ` at state` や ` at binding` がない点にご注意ください。実際、 この参照には何の装飾も施されていません。 このビューが機能する理由は、 ビュー本体内で` trip` の ` photoURL` プロパティを読み取っているからです。 これにより、このオブザーバブルクラスの ` photoURL` プロパティが 変更されるたびに、 ` trip` カードを更新する必要があることが SwiftUI に伝えられます。

    また、これは計算プロパティを 通じても機能します。 例えば、まだ写真が保存されていない ` trip` に対して、 プレースホルダー写真を使用したいとします。 UI でこれを処理するために、 「trip」クラスに「photo URL」や「placeholder」 といった計算プロパティを定義することができます。 この計算プロパティは、 その旅行に写真が定義されていない場合、 プレースホルダー写真を返します。 そして、ビュー本体では 「photo URL」の代わりに、 この新しい計算プロパティを使用します。

    SwiftUIは、計算プロパティに アクセスされた際に、このビュー本体内で 基になるプロパティ「photo URL」 が読み込まれていることを判別できます。 そのため、基になる「photo URL」 が変更されるたびに、 SwiftUIはトリップカードを更新します。

    さて、まとめますと、 このアプリでは「trip」 と「activity」オブジェクトから なる構造化された データモデルを使用しています。 各オブジェクトをモデル化するために 参照型やクラスを使用しており、 これにより参照を使って オブジェクト間の関係をモデル化できるほか、 UI内のどこからでもこれらのプロパティを 簡単に編集できるようになっています。

    これらのクラス内のデータをSwiftUIに 反映させるには、 各クラスの定義に` observable` マクロを追加するだけです。 そうすれば、SwiftUIのビューは ビュー本体内でプロパティを直接読み 取ることができます。

    さて、もう一つ行う必要があることがあります。 これまでご紹介した方法は問題なく動作します。 ビューがすでに「trip」のようなオブジェクトへの 参照を持っている場合です。

    先ほど、これらのオブジェクトはすべて データソースクラスが 所有していると述べましたが、 ビューに対してどのデータソースインスタンスを 使用すべきかを、 どのように指示すればよいのでしょうか?

    実は、これを行う方法の一つについてはすでに 説明しました。それは 「at state」から始まります。

    「at state」では、 ビューが存在する限り存続する オブジェクトを作成することを思い 出してください。そのため、アプリの最上部で、 データソースオブジェクトを保持する「at state」 プロパティを作成することができます。 このアプリの宣言に「at state」 を記述することで、アプリが存在する限り 存続するオブジェクトが作成され、 それをビューに受け渡すことができます。

    さて、これは非常にシンプルなビュー階層ではうまく 機能するかもしれません。 このアプリでは、UIのさまざまな部分で、 データソースへのアクセスが 必要になる場合があります。 例えば、旅行の完全なリストを取得する場合で、 ビュー階層が非常に単純であれば、 データソースのようなオブジェクトを、 それを必要とするビューにそのまま渡すのは、 まったく理にかなっています。

    しかし、アプリの複雑さが増すにつれて、 このアプローチは煩雑になり 始める可能性があります。 ビューが何層もネストされたアプリでは、 データソースを必要とするより 深い階層のビューにそれを渡すためだけに、 データソースへの参照を渡して 保存する必要が生じる可能性があります。

    そこで、この問題を回避するために、 このようなケースでは「環境」 を活用するのが適しています。

    「環境」とは、アプリの一部を構成する 本質的なプロパティであり、頻繁に 変更されるものではないと考えてください。

    この場合、データソースオブジェクトを ステートとして作成し、 そのオブジェクトをビューの環境に設定します。 これにより、データソースを 必要とするビューが、 この特定のインスタンスで構成されます。

    データソースオブジェクト自体は頻繁に 置き換えられることがないため、 この方法は安全です。このオブジェクトは オブザーバブルであり、アプリ内にはその 参照を必要とするさまざまなビューが 多数存在します。 したがって、データソースを 環境に配置することで、 その参照を必要とする ビューは、直接取得できるようになります。

    環境は、それが適用されている ビュー階層全体に波及します。 環境から値を要求するだけで、 SwiftUIがそれを 提供してくれます。

    例えば、ビュー階層のより深い 位置にある「最近の旅行」 ページのビューでは、プロパティに. SwiftUIは、この参照の値に、 環境内から一致する 型のオブジェクトを代入します。

    データソースは オブザーバブルであるため、ビューは ビュー本体内から直接、 そのプロパティへの依存関係を確立できます。 ここでは、「最近追加された 旅行」というプロパティが ビュー本体内で読み取られているため、 アプリに新しい旅行が追加されるたびに、 「最近の旅行」ページビューが 更新されます。

    このように、ビューの状態とデータモデルは、 現時点でこのアプリに 必要なデータフローの多くをカバーしています が、少し異なる アプローチをとるユースケースが 他にもいくつかあります。 そこで、このアプリにおける 設定(プリファレンス) と構成について、引き続き説明していきます。

    先ほど、ユーザーが旅行をタップすると、 表示されるアクティビティのリストを名前順や 完了状況で並べ替えることが できるとお話ししました。

    アプリはこの設定を保存しておく必要があり、 ユーザーがこのビューにアクセスするたびに、 そのユーザーが指定した並べ替え 方法が適用されるようにします。 さて、この設定は先ほど 説明したデータモデルの中に組み 込むにはあまり適していません。 というのも、これは旅行そのものとは 直接関係がないからです。 これは、ユーザーが アプリのさまざまな機能をどのように 利用したいかを追跡するためのものです。

    そこで、この並べ替え機能を実装するには、 まず新しい状態を定義し、 その状態を使って現在使用されている 並べ替え方法を追跡することから始められます。

    この例では、それを「sort option」 と呼びます。 そして、アクティビティのサブビューが、 アクティビティのレイアウトを決定する際にこの 「sort option」を読み取ります。

    これで機能し、アクティビティは ユーザーがメニューで選択した内容に従って並べ 替えられるようになりました。 しかし、このような「at state」 プロパティは、ビューの存続期間中のみ 保存されることを思い出してください。 そのため、ユーザーが 一度このビューを離れてから戻ってくると、 並べ替えは常にデフォルト( タイトル順)に戻ってしまいます。 ユーザーが旅行詳細ビューに戻った際には、 前回選択したのと同じ順序で 並べ替えられるようにしたいと考えています。

    そこで、これを実現するために、 ` at state` を ` at app storage` に変更し、 設定に一意の識別子を割り当てます。

    ` App Storage` の動作は、 ` at state` と非常に似ています。 アプリ全体で共有される状態を宣言するもので、 シンプルな Codable 型との相性が最も良いです。

    ` App Storage` の値は、 実際には内部で自動的に ディスクに保存されます。 Appleプラットフォームでは「UserDefaults」 と呼ばれるAPIが 使用されており、アプリ用のキーと 値のセットを保存します。

    これは、設定や環境設定、 アプリの設定詳細を保存するのに 最適な場所です。

    そこで、並べ替えの設定をApp Storageの プロパティに保存することで、 ユーザーが多くの異なる旅行間を移動しても、 アクティビティは常にそのビューで 最後に選択されたオプション順に 並べ替えられるようになります。

    最後に、本日ご紹介したい 最後のユースケースは、永続化についてです。

    先ほどお見せした、アプリストレージを使用して 並べ替えの設定を保存した例は、 実はこの永続化の一例です。 SwiftUIは自動的に UserDefaults APIを使用して、 ディスク上のこのキーの値を取得し、 それに合わせてビューの値を設定します。

    また、並べ替えオプションに 別の値が設定された場合、 アプリストレージはその新しい値をUserDefaultsに 保存します。 そのため、たとえユーザーが1日後、 1週間後、あるいは 1ヶ月後にアプリに戻ってきたとしても、 並べ替えオプションのプロパティは 変更されるまで同じまま維持されます。

    もちろん、永続化したいのは 設定だけではありません。 このアプリには充実したデータモデルがあり、 ユーザーは間違いなく、 ウィッシュリストを数日、数週間、あるいはそれ 以上保存しておきたいと思うでしょう。 そこで、アプリに永続性を備えたこのような データモデルを構築するには、 「Swift Data」が 優れた選択肢の一つとなります。

    Swift Dataは、最小限の コードと外部依存関係なしで、 アプリに迅速に永続性を追加できる フレームワークです。

    マクロやプロパティラッパーといった最新の Swift言語機能を活用しており、 Swiftコードを書くだけで モデルを定義することができます。

    デフォルトでは、実績のあるCore Dataの 永続化機能を活用しています。 Swift Dataのテクノロジーや モデルはすべて、 自動的にオブザーバブルになります。

    Swift Dataについてさらに詳しく 知りたい方は、 「Swift Dataの紹介」 や「Swift Dataを使ったアプリ開発」 といった動画をご覧ください。 先ほどお伝えしたように、 データモデルはいくつかのクラスで 構成されており、 各属性やクラス間の関係は、 それぞれのクラスのプロパティとして 保存されています。 現在、これらのクラスには ` observable` マクロが適用されています。

    しかし、 Swift Data を使用してこれらを永続化したい場合は、 ` observable` マクロを ` model` マクロに 置き換えるだけで済みます。

    ` model` マクロは、 これらのクラスを Swift Data モデルに変換します。 また、これにより自動的に オブザーバブルにもなります。

    そこで、ちょっとした 練習として、サンプルコードが 公開されたらダウンロードし、 いくつかの手順を踏んでこのアプリをSwift Dataに 移行してみてください。 興味のある方のために、 コード内で変更すべき 重要な点をいくつかご説明します。 まず、モデルにメタデータを 追加する必要があります。 アプリ内のビューからデータを取得したり クエリを実行したりする方法を調整し、 モデルを格納するためのコンテナを 設定することになります。 そこで、これらの手順についてそれぞれ 簡単に触れていきます。

    まず、モデルを「Observable」 から「Appモデル」に 切り替えた後、 各モデルを確認し、Swift Dataに 詳細情報を提供したい プロパティにアノテーションを付与します。 たとえば、tripモデルでは、 activitiesプロパティにatリレーションシップを 使用して、 tripとactivityの 関係を定義できます。 ここでは、削除ルールをcascadeに 設定しました。 これにより、tripが削除されると、 そのtripに関連するすべての activityも削除されます。 また、tripプロパティの逆リレーションシップを、 activityに 対するtripプロパティの逆リレーションシップに 設定しました。 つまり、これらのアクティビティの ` trip` プロパティは、常にそれらが 属する旅行を指し示すことになります。

    Swift Data を使えば、 ビュー内でモデルを取得して 表示するのが非常に簡単になります。 ` at` クエリを使用することで、 希望する順序でソートされ、 フィルタリングされた モデルの配列を Swift Dataに 要求することができます。 このスニペットでは、先ほどお見せした 「最近の旅行」ページビューを更新しました。 以前は、データソースオブジェクトを使用して 最近追加された旅行のリストを 取得していましたが、 Swift Data を使えば、 代わりに ` at` クエリを使用するだけで済みます。 このクエリは、 Swift Data に対し、作成日順に降順で ソートされた旅行の配列を提供するよう 要求するものです。

    その後、ビュー本体では、この「最近追加された旅行」の 配列を ` for each` ループ内で使用します。 新しい旅行が追加されるなど、 クエリの結果が変更された場合、 Swift Dataはこのビューを自動的に 更新します。そして最後に、アプリ宣言内で、 モデルコンテナ修飾子を追加し、 モデル型の名前を指定することで、 モデルを格納するためのコンテナを設定します。 アプリはモデルに対して デフォルトのコンテナを使用するため、 これら3つの変更、 プロパティメタデータの追加、 クエリの絞り込み、 そしてモデルコンテナの追加が、 始めるための鍵となります。 これにより、Swift Dataの強力な 永続化機能が、このようなアプリにも 活用できるようになります。 これで、ウィッシュリストアプリの データフローに 関するユースケースをすべて解説しました。 皆さんも、ご自身の SwiftUI

    アプリで同様のアプローチを取り 入れることができるでしょう。 アプリ内のビューが、 ボタンがタップされたときなど、 単純な UI 状態を追跡するだけでよい 場合は、 ` at` を使用し、 バインディングを使って他のビューや コントロールとその状態を 共有できるようにします。

    クラスなどの参照型を使用して 構築するリッチなデータモデルには、 「observable」 マクロの使用をご検討ください。

    データを保存したい場合。 データをストレージに 保存して、永続化させましょう。 設定やプリファレンスなどの小さなデータには、 アプリストレージをご利用ください。 また、モデルデータには Swift Dataフレームワークのご利用を ご検討ください。 お時間をいただき、ありがとうございました。 イベントの残りの時間も、 どうぞお楽しみください。 それでは、リーアさんにお返しします。

デベロッパ向けフッタ

  • ビデオ
  • Meet with Apple
  • SwiftUIにおけるデータフロー
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    メニューを開く メニューを閉じる
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • AIと機械学習
    • Apple Intelligence
    • オーディオとビデオ
    • 拡張現実
    • ビジネス
    • デザイン
    • 配信
    • 教育
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内購入
    • ローカリゼーション
    • マップと位置情報
    • セキュリティ
    • Safari/Web
    メニューを開く メニューを閉じる
    • ドキュメント
    • ダウンロード
    • サンプルコード
    • ビデオ
    • ドキュメントのアーカイブ
    メニューを開く メニューを閉じる
    • ヘルプガイドと記事
    • お問い合わせ
    • フォーラム
    • フィードバックとバグの報告
    • システムステータス
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(証明書、ID、プロファイル)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • セキュリティ報奨金プログラム
    • Security Research Device Program
    メニューを開く メニューを閉じる
    • Appleに相談
    • Apple Developer Center
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academy
    • WWDC
    最新ニュースを読む
    Apple Developerアプリを入手
    bilibili、LinkedIn、WeChat、YouTubeでフォロー
    Copyright © 2026 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン