CoreData + SwiftUI

May 01 2023
여기에서 원본 기사를 볼 수 있습니다. 최근 SwiftUI 및 CoreData를 사용하여 앱을 빌드해야 했습니다. 나는 CoreData가 UIKit과 거의 비슷하게 사용된다고 생각했지만 분명히 약간의 차이점이 있습니다.
Unsplash에 있는 Michael Dziedzic의 사진

여기에서 원본 기사를 볼 수 있습니다

최근에 SwiftUICoreData를 사용하여 앱을 빌드해야 했습니다 .

나는 CoreData가 UIKit과 거의 비슷하게 사용된다고 생각했지만 분명히 약간의 차이점이 있습니다.

이 가이드는 SwiftUI와 결합된 CoreData를 사용한 경험을 요약하기 위한 것입니다. 다른 측면을 찾으면 이 가이드에 추가하겠습니다.

자, 더 이상 고민하지 않고 시작하겠습니다.

설정

이것은 매우 직관적인 부분입니다.

  • 새 프로젝트를 시작하는 경우 사용자 데이터를 클라우드에 저장하려면 ' Use Core Data ' 옵션과 ' Host in CloudKit '을 선택할 수 있습니다. 이 경우 XCode가 프로젝트 설정을 처리합니다. (CloudKit 부분의 경우 몇 가지 추가 단계를 수행해야 합니다.)
  • 이미 프로젝트가 있는 경우 Persistence.swift 파일과 CoreData 스택을 초기화하는 swift 파일을 만들어야 합니다 . (이전 단계에 따라 새 프로젝트를 만들고 XCode에서 생성된 Persistence.swift 파일을 프로젝트에 복사할 수도 있습니다.

이제 프로젝트가 있으므로 보기 내에서 CoreData를 사용할 수 있으려면 managedObjectContext보기 계층 구조를 아래로 전달해야 합니다.

일반적으로 이것은 [appname]App.swift 파일 에서 수행됩니다 .

PersistenceController ( 예제 ) 는 '코어 데이터 사용' 옵션을 선택한 상태에서 새 프로젝트를 시작할 때 XCode가 자동으로 생성하는 구조체입니다.

@main
struct ExampleApp: App {

  let persistenceController = PersistenceController.shared

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

좋습니다. 이제 뷰에서 NSManagedObjects를 생성, 읽기, 업데이트 및 삭제할 수 있습니다.

CoreData로 작동

CoreData를 사용하려면 NSManagedObjectContext에 액세스해야 합니다 . 이렇게 하려면 두 가지 옵션이 있습니다.

  • 뷰에서 @ Environment 래퍼 사용
  • @Environment(\.managedObjectContext) private var viewContext
    

    @EnvironmentObject private var persistenceController: PersistenceController
    

do {
  if container.viewContext.hasChanges {
    try container.viewContext.save()
  }
} catch {
  print(error)
}

NSManagedObject를 저장하려면 먼저 인스턴스화하고 속성을 구성해야 합니다. 그런 다음 컨텍스트를 저장합니다.

let note = Note(context: container.viewContext)
note.id = id
note.text = text
note.folder = folder
note.creationDate = Date()
saveContext()

개체 가져오기

이제 가져오기 부분에서 가장 어려움을 겪었습니다. 바로 시작합시다.

SwiftUI에서 객체를 가져오는 가장 편리한 방법은 CoreData에서 읽어야 하는 모든 단일 뷰에서 @FetchRequest 또는 @SectionedFetchRequest 래퍼를 사용하는 것입니다.

가져온 개체를 보기 간에 전달하면 개체를 추가, 편집 또는 삭제할 때 자동 업데이트가 중단됩니다. (업데이트를 중단하지 않고 가져오기 개체를 전달하는 방법을 알고 있는 경우 알려주시면 이 가이드를 업데이트하겠습니다.)

따라서 CoreData 개체 및 자동 업데이트가 필요한 모든 뷰에 @FetchRequest를 추가해야 합니다 . 나는 그것이 약간 성가신 것을 알고 있지만 그만한 가치가 있습니다.

따라서 코드는 다음과 같습니다.

@FetchRequest(entity: \Object.type,
              sortDescriptors: [NSSortDescriptor],
              predicate: NSPredicate,
              animation: .default)
var objects: [Object]

@SectionedFetchRequest(entity: \Object.type,
                         sectionIdentifier: \Object.property,
                         sortDescriptors: [NSSortDescriptor],
                         predicate: NSPredicate,
                         animation: .default)
var sections: SectionedFetchResults<YourSectionType, Object>

List(sections) { section in
  Section(section.id) {
    ForEach(section) { object in
      // Configure your view with the object
    }
  }
}

객체를 추가, 업데이트 또는 삭제할 때마다 @FetchRequest 또는 @SectionedFetchRequest를 사용하면 보기가 자동으로 업데이트됩니다.

이제 상위 뷰에서 전달된 매개변수가 있는 NSPredicate 와 함께 @FetchRequest를 사용해야 하는 경우 다음 옵션이 훌륭하게 작동한다는 것을 알았습니다.

@FetchRequest
var objects: FetchedResults<Object>

init(id: ID) {
  _objects = FetchRequest<Object>(predicate: NSPredicate(format: "id == %@", id))
}

개체 업데이트

를 업데이트하려면 이전에 설명한 대로 를 업데이트하고 NSManagedObject가져오고 해당 속성을 업데이트해야 합니다 . NSManagedObject그런 다음 컨텍스트를 저장합니다.

note.text = newText
note.folder = newFolder
saveContext()

삭제하려면 이전에 설명한 대로 업데이트하고 가져와서 삭제 NSManagedObject해야 합니다 .NSManagedObject

viewContext.delete(object)

결론

이것이 SwiftUI와 함께 사용되는 CoreData에 대해 지금까지 발견한 전부입니다. 이 가이드는 지속적으로 업데이트됩니다.

더 나은 방법을 제안하고 싶다면 의견을 남겨주세요 . 최선의 선택으로 이 가이드를 업데이트하겠습니다.

SwiftUI 및 iOS 개발 여정에 도움이 되었기를 바랍니다.

이 기사가 마음에 드셨다면 LEAVE A CLAP 정말 감사합니다.

다음 가이드에서 만나요!

내 작업을 지원하고 작동 중인 이 가이드를 보려면 BrainDump — Notes & Writing을 확인하십시오 .

감사합니다