[Swift] SwiftData 모델 구조 변경 시 런타임 에러 해결하기

2025. 10. 13. 21:30·Apple/Swift
728x90
반응형

안녕하세요! 피피아노입니다 🎵

 

SwiftData를 사용해서 앱을 개발하다 보면 한 번쯤 이런 경험을 하게 됩니다.

 

모델 구조를 살짝 바꿨을 뿐인데 앱이 실행되자마자 바로 런타임 에러가 발생하는 경우 말이죠.

 

물론 개발 중이라면 앱을 삭제하고 다시 설치하면 문제없이 돌아가지만, 출시된 앱이라면 “앱을 지우고 다시 설치하세요”라고 안내할 수도 없습니다. 그리고 무엇보다 매번 삭제하면서 앱을 빌드하고 테스트하기가 귀찮습니다...

 

그렇다면 이 문제는 왜 발생하고, 어떻게 해결해야 할까요?

 

원인 - SwiftData의 내부 구조

SwiftData는 내부적으로 SQLite 기반의 데이터베이스를 사용합니다.

@Model로 정의한 구조체는 단순한 Swift 타입이 아니라, SwiftData가 해당 구조를 읽어서 데이터베이스 스키마를 자동으로 생성해줍니다.

 

즉, 모델 구조가 "데이터베이스 설계도" 역할을 하고 있는 것입니다.

그래서 아래와 같은 변경이 발생하게 되면 기존 DB(데이터베이스)의 구조와 불일치하게 되어 충돌이 발생해서 앱이 크래시가 발생합니다.

변경 내용 결과
프로퍼티 추가 새로운 컬럼이 DB에 없음
프로퍼티 타입 변경 기존 데이터와 호환 불가
프로퍼티 삭제 DB 컬럼이 존재하지만 모델에 없음
관계(@Relationship) 변경 참조 무결성 깨짐

 

이런 경우 SwiftData는 DB를 열 수 없다고 판단하고 앱을 중단시킵니다.

 

개발 중이라면 앱 삭제로 DB를 초기화하면 되지만, 사용자 데이터가 있는 실제 서비스 환경에서는 치명적인 문제입니다.

 

개발 중에 임시로 해결하는 방법

개발 단계에서는 DB를 깨끗하게 비워버리는 방법이 사실 가장 간단하긴 합니다.

  • 앱을 삭제하고 다시 설치
  • 시뮬레이터에서 "Erase All Content and Setting" 실행
  • ModelContainer를 임시로 메모리 전용(isStoredInMemoryOnly: true)으로 설정
let configuration = ModelConfiguration(
    schema: schema,
    isStoredInMemoryOnly: true
)

하지만 이 방법은 어디까지나 개발용 임시 해결책입니다.

해결책: 자동 마이그레이션(migrateAutomatically)

해당 문제를 해결하려면 자동 마이그레이션(migrateAutomatically) 기능을 사용하면 됩니다.

 

이 옵션을 설정하면 SwiftData가 모델 변경을 감지하고 가능한 범위 내에서 자동으로 스키마를 업데이트해줍니다.

import SwiftUI
import SwiftData

@main
struct TestApp: App {
    var sharedModelContainer: ModelContainer = {
        let schema = Schema([
            Project.self,
        ])

        let modelConfiguration = ModelConfiguration(
            schema: schema,
            isStoredInMemoryOnly: false,
            allowsSave: true,
            migrateAutomatically: true // 자동 마이그레이션 활성화
        )

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

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

자동 마이그레이션이 처리할 수 있는 변경 범위

변경 유형 자동 마이그레이션 가능 여부
새로운 프로퍼티 추가(기본값 있음) 가능
옵셔널 -> non-optional(기본값 존재 시) 가능
프로퍼티 삭제 불가능
프로퍼티 타입 변경(String -> Int) 불가능
관계(@Relationship) 구조 변경 불가능
이름 변경 @Attribute(.rename(from:)) 사용 시 가능

 

즉, 자동 마이그레이션은 가벼운 변경은 처리할 수 있지만, 타입 변경이나 관계 변경이 필요한 경우에는 직접 마이크레이션 코드를 작성해야 합니다.

수동 마이그레이션

수동 마이그레이션은 기존 데이터를 임시로 읽은 뒤, 새로운 모델 구조로 변환하여 다시 저장하는 방식입니다.

 

예를 들어, Project 모델의 프로퍼티 이름이나 타입이 바뀌었다면 앱 실행 시점에서 이전 데이터를 읽어서 새 모델 인스턴스로 매핑할 수 있습니다.

if let oldProjects = try? context.fetch(FetchDescriptor<OldProject>()) {
    for old in oldProjects {
        let new = Project(title: old.title, createdAt: old.date)
        context.insert(new)
    }
    try? context.save()
}

마무리

SwiftData는 편리하지만 내부적으로는 SQLite 기반의 엄연한 데이터베이스 시스템이기 때문에 모델 구조를 바꾸는 건 곧 DB 스키마를 바꾸는 것이고 그에 맞는 마이그레이션 과정을 반드시 고려해야 합니다.

 

저도 처음에는 앱이 크래시 날 때마다 앱을 지웠다가 다시 설치하면 된다고 생각했지만, 현업에서는 절대 이런 방법을 쓰지 않겠구나 라는 생각이 문득 들어서 이번 경험을 통해 정리를 해보았습니다. 다른 분들도 도움이 되셨으면 좋겠습니다!

 

감사합니다!


잘못된 내용이 있거나 더 좋은 내용 피드백은 언제나 환영합니다!

궁금하신 부분은 댓글로 질문 부탁드립니다!

728x90
반응형

'Apple > Swift' 카테고리의 다른 글

[Swift] 앱 인텐트 알아보기  (4) 2025.09.03
[Swift] Multipeer Connectivity 톺아보기  (5) 2025.08.23
[Swift] Swift Testing 톺아보기  (6) 2025.07.02
[Swift] suffix()로 인한 시간 초과 문제 해결하기  (8) 2025.06.27
[Swift] Foundation Models Framework  (6) 2025.06.22
'Apple/Swift' 카테고리의 다른 글
  • [Swift] 앱 인텐트 알아보기
  • [Swift] Multipeer Connectivity 톺아보기
  • [Swift] Swift Testing 톺아보기
  • [Swift] suffix()로 인한 시간 초과 문제 해결하기
P_Piano
P_Piano
Apple 생태계 개발자가 되기 위한 학습과 경험의 기록
    반응형
    250x250
  • P_Piano
    피피아노의 개발 일지
    P_Piano
  • 전체
    오늘
    어제
    • 분류 전체보기 (215)
      • Apple (133)
        • iOS (23)
        • visionOS (5)
        • Swift (71)
        • UIKit (2)
        • SwiftUI (24)
        • RxSwift (2)
        • Xcode (5)
      • C언어 (5)
      • C++ (8)
      • Dart (1)
      • Python (3)
      • JavaScript (17)
      • Git (1)
      • CS (39)
        • 디자인 패턴 (6)
        • 네트워크 (20)
        • 운영체제 (8)
        • Database (5)
        • 자료구조 (0)
      • IT 지식 (2)
      • IT 뉴스 (4)
      • 출처 표기 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    연산자
    네트워크
    옵셔널
    클래스
    디자인패턴
    코딩테스트
    Apple
    운영체제
    UIKit
    데이터베이스
    프로그래머스
    SWIFT
    티스토리챌린지
    ios
    함수
    Xcode
    프로세스
    visionOS
    swiftUI
    Initializers
    프로퍼티 래퍼
    오블완
    비동기
    배열
    Vision Pro
    스위프트
    이니셜라이저
    자바스크립트
    변수
    제어문
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
P_Piano
[Swift] SwiftData 모델 구조 변경 시 런타임 에러 해결하기
상단으로

티스토리툴바