
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를 지정해주면 된다.