import CoreData
struct CoreDataManager {
static let shared = CoreDataManager()
let container: NSPersistentContainer
var mainContext: NSManagedObjectContext {
container.viewContext
}
init(inMemory: Bool = false) {
container = NSPersistentContainer(name: "DataModel")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
}
import SwiftUI
@main
struct DataPersistenceApp: App {
let manager = CoreDataManager.shared
var body: some Scene {
WindowGroup {
MainList()
.environment(\.managedObjectContext, manager.mainContext)
}
}
}
@FetchRequest(sortDescriptors: [SortDescriptor(\MemberEntity.name, order: .forward)])
var members: FetchedResults<MemberEntity>
@Environment(\.managedObjectContext) var context
UIKit과는 다르게 @FetchRequest
를 사용하여 데이터 fetch
아래 선언된 FetchedResults<엔티티타입>
으로 전달됨
참고로 프리뷰쪽은 이렇게 주입해두어야 정상작동
static var previews: some View {
MemberCompose(editTarget: nil)
.environment(\.managedObjectContext, CoreDataManager.shared.mainContext)
}
func addMember() {
let newMember = MemberEntity(context: context)
newMember.name = name
newMember.age = Int16(age ?? 0)
do {
try context.save()
} catch {
//에러 처리
}
}
let editTarget: MemberEntity?
.onDelete(perform: delete(at:))
func delete(at rows: IndexSet) {
rows.forEach { index in
context.delete(members[index])
}
do {
try context.save()
} catch {
//에러 처리
}
}
FetchedResults<>
에서 subscript가 내부적으로 명시되어있기 때문에 index에 바로 접근 가능한 것. .searchable(text: $keyword)
.onChange(of: keyword, perform: { newValue in
members.nsPredicate = newValue.isEmpty ? nil : NSPredicate(format: "name CONTAINS[c] %@", newValue)
})
sortDescriptors
를 이용하자members.sortDescriptors
를 지정해주면 된다.