기어가더라도 제대로

[iOS-Swift] CoreData Object가 유일하다고 보장하기(feat. constraints) 본문

Swift - 데이터베이스

[iOS-Swift] CoreData Object가 유일하다고 보장하기(feat. constraints)

Damagucci-juice 2022. 12. 4. 03:54

전화번호가 같은 사람이 있을 수 있을까?

만약에 주소록을 만든다고하면, 동일한 번호가 있을 수가 없다. 예를들어 김철수의 번호와 안영미의 번호가 같을 수가 없는 것처럼, 그 엔티티에서 인스턴스끼리 어떤 프로퍼티는 유일함을 보장할 필요가 있다. 이것을 Core Data에서는 어떻게 할 수 있을까? 

이런 Entity가 있을 때 name 프로퍼티를 서로 겹치지 않게 각 오브젝트마다 고유하다고 설정을 한다면 어떻게 해야할까?

CoreData 에서 인스턴스의 프로퍼티를 유일하게 보장하기

  • Wizard 엔티티를 클릭하고 인스펙터를 보면 아래에 Constraints 가 있다. 그곳에 '+'를 누르자

  • "comma,separated,properties"를 클릭하고 'name'을 적는다.

동일한 데이터가 들어왔을 때 어떻게 다룰 것인가?

struct ContentView: View {
    @Environment(\.managedObjectContext) var moc

    @FetchRequest(sortDescriptors: []) var wizards: FetchedResults<Wizard>

    var body: some View {
        VStack {
            List(wizards, id: \.self) { wizard in
                Text(wizard.name ?? "Unknown")
            }

            Button("Add") {
                let wizard = Wizard(context: moc)
                wizard.name = "Harry Potter"
            }

            Button("Save") {
                do {
                    try moc.save()
                } catch {
                    print(error.localizedDescription)
                }
            }
        }
    }
}

  • 'Add' 버튼을 누르면 "Harry Potter" 라는 이름을 가진 마법사를 생성한다.
  • 이것을 'Save' 버튼을 눌러서 저장하면 어떻게 될까?
    • Core Data는 동일한 이름을 가진 오브젝트를 감지해서 세이브를 하지 않고 충돌을 낸다. 
    • 이를 해결하기 위해서 덮어쓰기 전략을 사용할 수 있다. 
  • CoreDataController.swift 에서 다음과 같이 선언할 수 있다. 
  • NSMergePolicy에서 인 메모리에 있는 값을 복제해서 덮어쓰는 전략을 사용한다는 뜻
  • 이제 Save를 하면 기능이 동작한다. 
import CoreData
import Foundation

class DataController: ObservableObject {
    let container = NSPersistentContainer(name: "CoreDataProject")
    
    init() {
        container.loadPersistentStores { description, error in
            if let error = error {
                print("Core Data failed to load: \(error.localizedDescription)")
                return
            }

            self.container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
        }
    }
}

 

Comments