State로 메모리에 데이터를 저장하면 앱을 껏다 켤 경우 휘발된다.
그래서 SwiftData는 앱 내 database, 즉 device에 저장가능하다.
프로젝트를 선택할때 Storage필드를 SwiftData로 설정하면 예제를 볼 수 있다
// App 진입점
@main
struct SwiftDataTestApp: App {
var sharedModelContainer: ModelContainer = { // 앱 전체에서 사용할 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)")
}
}() // 클로저 즉시 실행, sharedModelContainer에 초기값을 할당
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(sharedModelContainer)
// WindowGroup에 위에서 생성한 sharedModelContainer를 연결하여, 하위 뷰에서 데이터 모델에 접근할 수 있도록 함
}
}
// 데이터 모델 스키마 지정
import Foundation
import SwiftData
@Model
final class Item {
var title: String
init(title: String) {
self.title = title
}
}
// ContentView
import SwiftUI
import SwiftData
struct ContentView: View {
@Environment(\.modelContext) private var modelContext // 저장, 삭제에 사용
@Query private var items: [Item] // 조회, 수정에 사용
var body: some View {
NavigationSplitView { // NavigationStack for ipad
List {
ForEach(items) { item in
NavigationLink {
Text("다음화면")
} label: {
Text(item.title)
}
}
.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(title: "새로운 아이템")
modelContext.insert(newItem) // items가 아닌 modelContext에 접근
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
for index in offsets {
modelContext.delete(items[index]) // items가 아닌 modelContext에 접근
}
}
}
}
ContentView에서 데이터 모델을 사용할 때, 아래와 같이 사용
@Environment(.modelContext) private var modelContext // 저장, 삭제에 사용
@Query private var items: [Item] // 조회, 업데이트에 사용