[TIL] Core Data

박주하·2025년 7월 4일

Core Data


  • 앱의 데이터를 안전하고 체계적으로 보관하고 관리하는 프레임워크
  • 데이터들을 앱이 꺼지거나 휴대폰이 재부팅되어도 사라지지 않게 디스크에 저장하고, 필요할 때마다 검색, 수정, 삭제하는 역할
기능설명
저장소 관리데이터를 파일(DB)에 저장하고 꺼냄
검색특정 조건에 맞는 데이터만 빠르게 가져옴
객체 관계 관리관계형 모델 지원 (1\:N, N\:M 등)
메모리 캐싱메모리에 객체를 캐시해서 성능 향상
Undo/Redo 지원변경 이력 추적 기능도 있음

구성 요소

1. NSManagedObjectModel

  • 창고 설계도
  • 창고에 어떤 종류의 물건을(데이터 모델), 어떤 형태로 보관할지(속성) 정의하는 설계도(Entity)
  • 예: '일기'라는 물건은 '제목', '내용', '날짜'라는 공간에 보관한다고 미리 설계하는 것

2. NSPersistentStoreCoordinator

  • 창고 관리 총책임자
  • 설계도를 보고 실제 창고(데이터 저장소)를 지휘하는 총책임자
  • 작업 감독관(Context)에게 "이 물건은 저 선반에 넣어!" 또는 "저 선반에 있는 물건 좀 가져와!"라고 지시하며 실제 창고와의 통신 담당

3. NSManagedObjectContext

  • 작업 공간 & 작업 감독관
  • 가장 중요한 직원이며, 우리가 직접 소통하는 대상
  • 창고에서 물건을 가져오거나, 새 물건을 넣거나, 기존 물건을 바꿀 때, 우리는 이 감독관에게 요청(데이터를 CRUD하는 공간)
  • 감독관은 '작업 공간(메모리)'이라는 임시 공간에 물건들을 올려두고 모든 작업을 처리한 뒤, "이제 이대로 창고에 반영해줘!"라고 총책임자에게 보고 (메모리 내 임시 작업 영역)
  • 임시 공간에서 작업하기 때문에 실수로 작업을 잘못해도 쉽게 취소할 수 있고, 여러 작업을 한 번에 처리할 수 있어 효율적

4. NSPersistentContainer

  • 창고 관리 사무소
  • 위에서 설명한 설계도, 총책임자, 작업 감독관 등 모든 직원을 한 번에 채용하고 관리하는 편리한 사무소
  • Core Data의 설정과 저장소를 초기화/관리

5. NSManagedObject

  • 창고에 보관된 실제 물건
  • 작업 감독관(Context)이 관리하는, 창고에 저장되는 실제 데이터 객체
  • 예: '7월 4일의 일기'가 하나의 NSManagedObject가 됨

💡 요약

  • 우리는 작업 감독관(Context)에게 "이런 물건(Object)을 설계도(Model)에 맞게 창고에 넣어줘/가져와줘" 라고 요청
  • 나머지 복잡한 일은 알아서 처리해줌

UserDefaults vs Core Data

기능UserDefaultsCore Data
용도간단한 설정 저장복잡한 데이터 관리
검색 조건없음있음 (필터링, 정렬 등)
관계형 구조없음가능
성능낮음캐싱, 옵저버, 배치 처리로 빠름
데이터 양소량대량도 문제 없음

'할 일 목록' 앱


  • CRUD: 데이터를 다루는 가장 기본적인 4가지 작업
  • 생성(Create), 읽기(Read), 수정(Update), 삭제(Delete)

1. 할 일 생성 (Create)

  • Todo라는 Entity 생성
  • 속성: title: String, isDone: Bool
// 1. 작업 감독관(Context)을 불러옴
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

// 2. "할 일(Todo)"이라는 물건을 새로 하나 생성
let newTodo = Todo(context: context)

// 3. 물건의 속성 지정
newTodo.title = "코어 데이터 공부하기"
newTodo.isDone = false

// 4. 감독관에게 "작업한 내용을 실제 창고에 저장해줘!" 요청
do {
    try context.save()
    print("저장 성공!")
} catch {
    print("저장 실패: \(error)")
}

2. 할 일 목록 불러오기 (Read)

// 1. 작업 감독관(Context)을 불러옴
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

// 2. 감독관에게 "창고에 있는 '할 일(Todo)' 물건 전부 다 가져와줘!" 요청
do {
    let todoList = try context.fetch(Todo.fetchRequest()) as! [Todo]
    
    // 3. 가져온 목록을 하나씩 확인
    for todo in todoList {
        print("할 일: \(todo.title ?? ""), 완료 여부: \(todo.isDone)")
    }
} catch {
    print("불러오기 실패: \(error)")
}

3. 할 일 수정 (Update)

// 1. 작업 감독관(Context)을 불러옴
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

// 2. "할 일(Todo)을 찾아달라"는 기본 요청서를 준비
let fetchRequest = Todo.fetchRequest()

// 3. '검색 조건 명세서(NSPredicate)' 작성
// title 속성이 '코어 데이터 공부하기'와 같은(==) 데이터를 찾기
fetchRequest.predicate = NSPredicate(format: "title == %@", "코어 데이터 공부하기")

// 4. 감독관에게 이 '조건이 포함된 요청서'를 전달하여 데이터 검색
do {
    // 조건에 맞는 데이터 목록 받음
    let specificTodoList = try context.fetch(fetchRequest)
    
    // 5. 찾았는지 확인하고, 첫 번째로 찾은 항목 수정
    if let todoToUpdate = specificTodoList.first {
        todoToUpdate.isDone = true // 내용을 '완료'로 변경
        
        // 변경사항을 창고에 최종 저장
        try context.save()
        print("수정 및 저장을 완료했습니다!")
        
    } else {
        print("해당하는 할 일을 찾지 못했습니다.")
    }
    
} catch {
    print("데이터를 찾거나 저장하는 데 실패했습니다: \(error)")
}
  • 조건을 NSPredicate를 이용해 만들고, 작업 감독관(Context)에게 이 요청서와 함께 "물건을 찾아달라(fetch)"고 부탁

4. 할 일 삭제 (Delete)

// 1. 위와 같이 삭제할 할 일 찾은 후, 감독관에게 해당 물건 삭제 요청
context.delete(todoToDelete)

// 2. 감독관에게 변경사항(삭제된 내용)을 실제 창고에 반영하라고 요청
do {
    try context.save()
    print("삭제 성공!")
} catch {
    print("삭제 실패: \(error)")
}

0개의 댓글