ハイライト
SwiftData は、同じアプリケーション内で Core Data と共存できます。開発者は Xcode Assistant を使用して、ワンクリックで SwiftData モデル クラスを生成し、完全な移行を完了することができます。また、2 つの永続スタックが同じストレージ ファイルを共有して、すべてのコードを一度に書き換えることなく段階的な移行を実現することもできます。
主要内容
多くのアプリケーションは長年にわたり、複雑なデータ モデルと大量のコードを備えた Core Data 上で実行されてきました。 WWDC23 で SwiftData が発表された後、これらのアプリケーションの開発者は、「移行する必要があるか?」という現実的な問題に直面しました。移行方法は?
このセッションでは、完全移行、共存モード、Xcode からモデル クラスを自動的に生成するクイック エントリの 3 つのオプションが提供されます。中心的な考え方は柔軟性です。チームのリソース、バージョンの互換性要件、コードの複雑さに基づいて最適なパスを選択します。
SwiftData モデルクラスを自動生成する
(01:05) すでに Core Data をお持ちの場合.xcdatamodeldファイルを作成すると、Xcode は対応する SwiftData モデル クラスを自動的に生成するのに役立ちます。
操作手順:
1.Xcodeでモデルファイルを選択します 2. メニュー バーから [エディター] > [SwiftData コードの作成] を選択します。 3. 各エンティティに対応する Swift ファイルを生成します
生成された SwiftData モデルは次のようになります。
import SwiftData
@Model
class Trip {
var name: String
var destination: String
var startDate: Date
var endDate: Date
var livingAccommodation: LivingAccommodation?
var bucketList: [BucketListItem]?
}
キーポイント:
- 生成されたクラスは自動的に追加されます
@Modelマクロ - プロパティと関係はコア データ エンティティに 1 対 1 で対応します
- 新しい SwiftData アプリケーションを最初から作成する場合は、このアシスタントは必要ありません。直接記述するだけです。
@Model入力するだけ
完全な移行
(03:09) 完全な移行とは、Core Data の痕跡をすべて削除し、SwiftData に置き換えることを意味します。
移行前チェックリスト:
- 各コア データ エンティティには、対応する SwiftData モデル クラスが必要です
- エンティティ名は正確に一致する必要があります
- すべてのプロパティと関係は、SwiftData に対応する定義が必要です
- すべてのコアデータ機能が SwiftData でサポートされていることを確認しました
移行手順:
- Xcode Assistant を使用して SwiftData モデル クラスを生成します
- 削除
.xcdatamodeldファイル - 元の永続ファイル (コア データ スタックをセットアップするコード) を削除します。
4.使用する
.modelContainer()SwiftData スタックをセットアップする
(04:37) SwiftUI で ModelContainer を設定します。
@main
struct TripsApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(
for: [Trip.self, BucketListItem.self, LivingAccommodation.self]
)
}
}
キーポイント:
.modelContainer()コンテナとコンテキストを同時に作成する- コンテキストは SwiftUI 環境に自動的に挿入されます
- NSPersistentContainer を手動で管理する必要はありません
(04:57) オブジェクト作成の比較:
コアデータメソッド:
@Environment(\.managedObjectContext) private var viewContext
let newTrip = Trip(context: viewContext)
newTrip.name = name
newTrip.destination = destination
newTrip.startDate = startDate
newTrip.endDate = endDate
SwiftData の方法:
@Environment(\.modelContext) private var modelContext
let trip = Trip(
name: name,
destination: destination,
startDate: startDate,
endDate: endDate
)
modelContext.insert(object: trip)
キーポイント:
- SwiftData は、通常のイニシャライザを使用して、コンテキストを渡さずにオブジェクトを作成します。
- 作成後に呼び出されます
insert()永続性のためにマークされています - コードがシンプルになり、タイプセーフになりました
(05:51) 保存メカニズムも変更されました。 SwiftData は暗黙的な保存をサポートしています。
- UIライフサイクルイベントによる保存のトリガー
- コンテキストの変更後に定期的に自動的に保存します
- Core Data の明示的な呼び出しは削除可能
save()コード
(06:16) データは以下から取得されます。FetchRequestなる@Query:
@Query(sort: \.startDate, order: .forward)
var trips: [Trip]
キーポイント:
@Query直接戻る[Trip]としてパッケージ化する必要はありません。FetchedResults- ソートと述語をサポート- データの変更に応じて UI を自動的に更新します
共存モード
(06:51) 完全な移行が常に可能であるとは限りません。アプリが iOS 16 以下をサポートする必要がある場合、またはコードの量が多すぎて一度に書き換えられない場合は、共存モードの方が適しています。
共存モードでは、Core Data と SwiftData の 2 つの独立した永続スタックが同じストレージ ファイルを指すことができます。古いコードで Core Data を引き続き使用し、新しい機能で SwiftData を使用できます。
(07:30) 共存のための主要な構成を設定します。
let url = URL(fileURLWithPath: "/path/to/Trips.store")
if let description = container.persistentStoreDescriptions.first {
description.url = url
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
}
キーポイント:
- 両方のスタックが同じストレージ URL を指している必要があります
- 永続的な履歴追跡をオンにする必要があります
- SwiftData はこの機能を自動的にオンにします。Core Data は手動で設定する必要があります
- 有効にしない場合、ストレージは読み取り専用モードに設定されます
(08:51) クラス名の競合の処理:
// Core Data 类
class CDTrip: NSManagedObject {
// ...
}
// SwiftData 类
@Model final class Trip {
// ...
}
キーポイント:
- Core Data クラスと SwiftData クラスに同じ名前を付けることはできません
- Core Data クラス (CDTrip など) にプレフィックスを追加できます
- クラス名は変更されましたが、エンティティ名は同じままです
- 管理オブジェクト モデル エディターでクラス名を変更することもできます。
共存モードの追加要件:
- 2 つのスキーマは同期を保つ必要があり、分岐することはできません。
- 新しい属性と関係を同じ方法で両方のモデルに追加する必要があります
- エンティティのバージョン ハッシュが一致する必要があります。一致しない場合、予期しない移行がトリガーされます。
- マルチバージョンスキーマでは、バージョンの違いを正しく管理する必要があります
UIKit / AppKit アプリをどうするか
(10:25) SwiftData は SwiftUI と緊密に統合されていますが、UIKit および AppKit アプリケーションも使用できます。
- 共存ソリューション: UIKit コードは引き続き Core Data をバインドし、SwiftData は並行して新機能で使用されます。
- パッケージ化ソリューション: SwiftData クラスを通常の Swift クラスとして扱い、UIKit コードでラップします。
詳細
デシジョン ツリーを移行する
どの移行戦略を選択するかは、いくつかの要因によって決まります。
| 要因 | 完全な移行 | 共存モード |
|---|---|---|
| サポートされている最小バージョン | iOS 17以降 | iOS 16以前 |
| コード書き換えコスト | 高 (1 回) | 低 (増分) |
| チームリソース | 十分 | 限定 |
| データモデルの複雑さ | シンプルから中程度 | 複雑な |
| 長期保守 | もっと簡潔に | 2 セットのコードを維持する必要がある |
スキーマの互換性チェック
移行前に次のことを確認する必要があります。
- エンティティ名: Core Data エンティティ名 == SwiftData クラス名
- 属性名とタイプ: 完全一致
- 関係: SwiftData では双方向の関係が使用されます
@Relationshipマーク - 制約: 一意性制約に使用されます。
@Attribute(.unique)5. サポートされていない機能: 取得されたプロパティ、取得リクエストなど。
バージョン管理
共存モードでは、スキーマを変更するには両方のモデルを同時に更新する必要があります。
- コアデータ内
.xcdatamodeld新しいプロパティを追加する - SwiftData の場合
@Model対応する属性をクラスに追加します - 2 つのモデルのエンティティ バージョン ハッシュが一貫していることを確認します。
- バージョン管理されたスキーマを使用して SwiftData モデルのバージョンを管理する
重要ポイント
1.既存の Core Data アプリケーションに SwiftData を段階的に導入
- 対処法: 古い機能を変更せず、新しいモジュールで SwiftData を使用し、共存モードでデータを共有します。
- 実行する価値がある理由: リスクゼロで SwiftData を試してください。チームは学習と使用を同時に行うことができ、大規模なリファクタリングは必要ありません。
- 開始方法: 共存スタックを構成し、名前の競合を避けるためにコア データ クラスにプレフィックスを追加し、それを新しい関数で使用します。
@Queryそして@Model
2. Xcode Assistant を使用して SwiftData モデルを迅速に生成
- 何をすべきか: 既存のものを配置します
.xcdatamodeldSwiftData クラスに変換する - 実行する価値がある理由: 手書きのマッピング エラーを回避し、プロパティ名と型の一貫性を自動的に維持します。
- 開始方法: モデル ファイル > エディター > SwiftData コードの作成を選択し、生成されたクラスが期待どおりかどうかを確認します。
3.クロスバージョンのメモ作成アプリケーションを作成する
- 対処方法: iOS 16 および iOS 17 以降をサポートするメモ作成アプリ、iOS 16 は Core Data を使用、iOS 17 は SwiftData を使用します。
- 実行する価値がある理由: 共存モードでは、同じストレージ ファイルに 2 つのスタックからアクセスでき、ユーザー データはシームレスに移行できます。
- 開始方法: 実行時にシステム バージョンを決定し、Core Data スタックまたは SwiftData スタックを初期化することを選択し、同じストレージ URL を共有します。
4.従来の Core Data コードをリファクタリング
- 内容: 肥大化した Core Data コードを段階的に SwiftData に置き換えます
- 価値がある理由: ボイラープレート コードを削減し、型安全性を獲得し、SwiftUI との統合を改善します。
- 開始方法: 最も単純なエンティティから移行を開始し、データの整合性を検証した後、徐々に範囲を拡大します。使用
@Query交換するFetchRequest
関連セッション
- SwiftData の紹介 — 基本概念や API の使用法など、SwiftData の入門書
- SwiftData を使用してスキーマをモデル化する — バージョン管理されたスキーマを含む、SwiftData を使用したデータ モデリングについて詳しく学習します。
- SwiftData の詳細 — SwiftData の高度な使用法とパフォーマンスの最適化
- SwiftData を使用してアプリを構築する — SwiftData を使用して完全なアプリを最初から構築します
コメント
GitHub Issues · utterances