LoginSignup
1
2

忙しい人のための5分でSwiftDataの雰囲気をキャッチアップするメモ

Last updated at Posted at 2024-01-29

本記事について

本記事では、SwiftDataをざっくりキャッチアップしたメモです。
SwiftDataは、CoreDataのようにデータを永続化するフレームワークです。

今回はなんとなくSwiftDataの雰囲気を掴めることをゴールとします。

新規でプロジェクトと作るとSwiftDataの実装がすでに組み込まれています。
デフォルトで用意されている実装を使って解説します。

環境

  • Xcode: 15.1
  • iOS: 17.2
  • MacBool Air M2 / Sonoma 14.2.1

事前準備

下記3点を行います。

  • Xcodeで新規プロジェクトを作る。
  • 新規プロジェクト設定画面でStorageをSwiftDataに設定する。
  • OSの条件分岐は説明しないので削除する。

解説

モデルの設定

アプリのエントリポイントです。
データベース操作を行うための環境の準備を行います。

SampleSwiftDataApp.swift
@main
struct SampleSwiftDataApp: App {
    var sharedModelContainer: ModelContainer = {
        let schema = Schema([
            Item.self,
        ])
        let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)

        do {
            return try ModelContainer(for: schema, configurations: [modelConfiguration])
        } catch {
            fatalError("Could not create ModelContainer: \(error)")
        }
    }()

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(sharedModelContainer)
    }
}

スキーマを定義

let schema = Schema([
            Item.self,
        ])

定義したスキーマを使ってモデルの設定

let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)

ModelContainerの構築

ModelContainer(for: schema, configurations: [modelConfiguration])

最後にModelContainerを返します。
ModelContainerによって、データの操作を行います。

モデル定義

Item.swift
@Model
final class Item {
    var timestamp: Date
    
    init(timestamp: Date) {
        self.timestamp = timestamp
    }
}

@Modelマクロ

  • @ModelマクロでItem型のモデルクラスを定義します。
  • Itemインスタンスを保存できます。

View側

次にView側の説明です。

ContentView.swift
import SwiftUI
import SwiftData

struct ContentView: View {
    // 解説
    @Environment(\.modelContext) private var modelContext
    // 解説
    @Query private var items: [Item]

    var body: some View {
        NavigationSplitView {
            List {
                ForEach(items) { item in
                    NavigationLink {
                        Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))")
                    } label: {
                        Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
                    }
                }
                .onDelete(perform: deleteItems)
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    EditButton()
                }
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
        } detail: {
            Text("Select an item")
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(timestamp: Date())
            // 解説
            modelContext.insert(newItem)
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            for index in offsets {
                // 解説
                modelContext.delete(items[index])
            }
        }
    }
}

// 解説
#Preview {
    ContentView()
        .modelContainer(for: Item.self, inMemory: true)
}

モデルのフェッチ、挿入、削除、および変更への保存可能なオブジェクト

@Environment(\.modelContext) private var modelContext

指定したモデルをfetchし、データ管理を行う

@Query private var items: [Item]

サンプルだと、配列化するだけですが、
公式だと下記のようにソートなども可能です。

@Query(sort: \.startDate, order: .reverse)

データの追加・削除

modelContext.insert(newItem)

modelContext.delete(items[index])

View内でデータ操作を行うためのモディファイア

Xcode Preview内でデータ操作を行うことができます。ただし、データ保存までは行いません。

ContentView()
    .modelContainer(for: Item.self, inMemory: true)

最後に

雰囲気を掴んでいただけたら嬉しいです。

参考文献

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2