SwiftData를 처음 써보면 정말 놀라는 포인트가 하나 있다.
modelContext.save()를 호출하지 않았는데도 데이터가 저장되는 현상을 밝견했다.
문제를 발견한 코드는 다음과 같다.
struct TodoDetail: View {
@Binding var todo: TodoList
@Environment(\.modelContext) private var modelContext
...생략
.padding()
.navigationTitle("할 일을 작성하세요.")
.toolbar{
ToolbarItem{
Button("저장") {
do {
// 주석처리 했음에도 불구하고, 저장이 된다.
// try modelContext.save()
}
catch {
print("Error Context Save: \(error)")
}
}
}
}
}
}
... 생략
SwiftData는 과연 언제, 어떤 조건에서 데이터를 자동 저장하는 걸까?
SwiftData는 Core Data 위에 만들어진 새로운 추상화 계층이다.
그리고 SwiftUI와 찰떡같이 맞춰주기 위해 자동 저장 기능이 추가됐다.
그러니까 핵심은 이거다:
SwiftData는 특정 시점에 자동으로 데이터를 저장한다.
그럼 여기서 궁금한 게 하나 생긴다.
그 특정 시점이 언제냐는 거다.
SwiftData에서 자동 저장은 다음 조건에서 '발생할 수 있다'고 한다.
여기서 중요한 건 "항상 발생한다"가 아니라 "발생할 수 있다"라는 점이다.
| 상황 | 설명 |
|---|---|
| 뷰가 pop되거나 dismiss될 때 | NavigationStack이나 Sheet가 닫힐 때 |
| 앱이 백그라운드로 전환될 때 | AppDelegate 수준에서 저장 트리거 |
| 앱이 종료될 때 | OS 상황에 따라 다름 |
| 일정 시간 경과 | "주기적 저장"은 보장되지 않음 |
| 메모리 압박 | 오히려 저장 없이 종료될 위험 |
딱 정리하자면,
자동 저장은 "뷰가 사라질 때" 가장 확실하게 일어난다.
그 외의 경우는 절대적으로 믿으면 안 된다. 앱이 종료되거나 메모리가 부족해지면 데이터가 날아갈 수도 있다.
내가 작성한 코드에서 modelContext.save()는 없었다.
근데 TextField와 TextEditor에 @Binding var todo: TodoList가 직접 연결돼 있었고,
이 상태에서 값을 입력하면 SwiftData의 ModelContext는 자동으로 변화(hasChanges)를 감지한다.
그리고 이 뷰가 pop되거나 dismiss되는 순간,
SwiftData는 알아서 context.save()를 호출한다.
결국 이 말은,
자동 저장은 내가 뷰를 닫는 그 타이밍에 발생한 것이다.
이럴 땐 이렇게 하면 된다:
@State private var tempTitle: String = ""
@State private var tempDesc: String = ""
.onAppear {
tempTitle = todo.title
tempDesc = todo.todoDesc
}
Button("저장") {
todo.title = tempTitle
todo.todoDesc = tempDesc
try? modelContext.save()
}
@Binding 대신 @State에 임시 값을 담아두고,
사용자가 직접 저장 버튼을 눌렀을 때만 모델을 수정하는 방식이다.
이러면 자동 저장을 피하고 내가 원하는 타이밍에만 저장할 수 있다.
SwiftData를 제어하려면 이런 식으로 한 번 더 래핑해주는 게 좋다.
한 줄 요약:
SwiftData는 뷰가 사라질 때 자동 저장이 일어난다. 하지만 그 외 상황은 보장되지 않으므로 수동 저장 흐름이 필요할 수 있다.
| 핵심 정리 |
|---|
@Binding은 즉시 모델을 수정한다 |
| 뷰가 사라질 때 SwiftData가 자동 저장한다 |
| 다른 상황에서는 자동 저장이 보장되지 않는다 |
안전하게 저장하려면 @State를 활용해 수동 저장 흐름을 만들자 |
SwiftData가 정말 매력적인 이유는 SwiftUI와 자연스럽게 동작하기 때문이다.
하지만 반대로, 자동으로 너무 많은 걸 처리해줘서
개발자가 직접 제어하고 싶을 땐 조금 까다로워질 수도 있다.
필요하면 이 글을 기반으로 추가적인 실험 결과나 예제를 더 작성해도 좋겠다.
다음엔 @Model, @Query, 그리고 관계 설정 쪽도 정리해볼 예정이다.