SwiftUI에서 CoreData 통합하기: 데이터 지속성 관리

작성일 :

SwiftUI에서 CoreData 통합하기: 데이터 지속성 관리

SwiftUI는 애플의 선언형 UI 프레임워크로, 모바일 애플리케이션 개발을 혁신적으로 단순화합니다. 그러나 데이터 지속성 문제는 여전히 남아있고, 이를 해결하기 위한 대표적인 방법이 CoreData와의 통합입니다. 이번 글에서는 SwiftUI에서 CoreData를 통합하여 데이터 지속성을 어떻게 관리할 수 있는지 단계별로 살펴보겠습니다.

CoreData 시작하기

CoreData는 객체 그래프 관리와 데이터 지속성을 위한 프레임워크입니다. CoreData를 프로젝트에 추가하려면 Xcode에서 새로운 데이터 모델 파일을 만들어야 합니다.

  1. 프로젝트 설정

    • Xcode에서 프로젝트를 생성합니다.
    • File > New > File 메뉴를 선택한 후, Core Data를 선택하여 Data Model 파일을 만듭니다.
  2. 데이터 모델링

    • 데이터 모델 파일을 열어 Entity와 Attribute를 정의합니다.
    • 예를 들어, Item이라는 Entity에는 name(String)과 timestamp(Date) 속성을 추가합니다.
swift
import Foundation
import CoreData

extension Item {
    @nonobjc public class func fetchRequest() -> NSFetchRequest<Item> {
        return NSFetchRequest<Item>(entityName: "Item")
    }

    @NSManaged public var name: String?
    @NSManaged public var timestamp: Date?
}

SwiftUI와 CoreData 결합하기

SwiftUI에서 CoreData를 사용하려면 NSPersistentContainerNSManagedObjectContext를 설정해야 합니다.

  1. 환경 설정
    • AppDelegate 또는 새로운 Swift 파일에 CoreData 스택을 설정합니다.
swift
import SwiftUI
import CoreData

@main
struct CoreDataDemoApp: App {
    let persistenceController = PersistenceController.shared

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}

class PersistenceController {
    static let shared = PersistenceController()

    let container: NSPersistentContainer

    init() {
        container = NSPersistentContainer(name: "ModelName")
        container.loadPersistentStores { _, error in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
    }
}
  1. 환경 변수 사용
    • @Environment 속성을 사용하여 SwiftUI 뷰에서 managed object context를 접근합니다.
swift
struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        List {
            ForEach(items) { item in
                Text("Item at \(item.timestamp!, formatter: itemFormatter)")
            }
        }
        .toolbar {
            ToolbarItem(placement: .primaryAction) {
                Button(action: addItem) {
                    Label("Add Item", systemImage: "plus")
                }
            }
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()
            saveContext()
        }
    }

    private func saveContext() {
        do {
            try viewContext.save()
        } catch {
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
    }
}

데이터 저장 및 가져오기

데이터를 저장하거나 가져오려면 NSManagedObjectContextsave()fetchRequest 메서드를 사용합니다. 이 예제에서는 addItem 메서드를 통해 새로운 데이터를 추가하고 FetchRequest를 통해 데이터를 가져옵니다.

swift
private func addItem() {
    withAnimation {
        let newItem = Item(context: viewContext)
        newItem.name = "Sample Item"
        newItem.timestamp = Date()
        saveContext()
    }
}

private func saveContext() {
    do {
        try viewContext.save()
    } catch {
        let nsError = error as NSError
        fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    }
}

CoreData 모델에 새로운 엔터티나 속성을 추가할 때마다, NSManagedObject 서브클래스와 해당 속성에 대한 코드를 업데이트해야 합니다. 이를 위해 Xcode의 코드 생성 기능을 사용하거나 직접 구현할 수 있습니다.

정리

SwiftUI에서 CoreData를 통합하여 데이터 지속성을 관리하는 방법을 알아보았습니다. 데이터 모델링부터 SwiftUI와의 연동, CRUD 작업을 모두 다루었습니다. 이렇게 통합된 시스템을 통해 더욱 견고하고 유지보수하기 쉬운 iOS 애플리케이션을 개발할 수 있습니다.