[SwiftUI] CRUD

RudinP·2025년 8월 23일
0

Study

목록 보기
347/352

CRUD의 의미

  • Create, Read, Update, Delete

1. DataModel 파일에 엔티티 추가

  • Class 이름은 ~Entity

2. CoreDataManager 생성

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
    }
}

3. App파일에서 environment 주입

import SwiftUI

@main
struct DataPersistenceApp: App {
    let manager = CoreDataManager.shared

    var body: some Scene {
        WindowGroup {
            MainList()
                .environment(\.managedObjectContext, manager.mainContext)
        }
    }
}

4. 데이터 사용하는 곳에서 environment 변수 선언(Read)

@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)
    }

엔티티 추가(Create)

    func addMember() {
        let newMember = MemberEntity(context: context)
        newMember.name = name
        newMember.age = Int16(age ?? 0)
        
        do {
            try context.save()
        } catch {
            //에러 처리
        }
    }

엔티티 업데이트(Update)

let editTarget: MemberEntity?
  • 업데이트 여부 판단할 변수 선언
  • 이후 해당 변수의 존재 여부에 따라 create인지 update인지 구분하여 처리(context.save부분 자체는 create와 동일하다.)

엔티티 삭제(Delete)

.onDelete(perform: delete(at:))
  • 리스트였다는 가정 하, onDelete 모디파이어 사용
    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)
        })
  • nsPredicate 를 동적으로 바꿔주면 됨

정렬

  • sortDescriptors를 이용하자
  • 이 상황에서는 members.sortDescriptors를 지정해주면 된다.
profile
iOS 개발자가 되기 위한 스터디룸...

0개의 댓글