[iOS] Core Data

Lena·2020년 12월 18일
0
post-custom-banner

Core Data

Use Core Data to save your application’s permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device.

Core Data를 사용함으로써 application에 영속적인 데이터를 저장할 수 있게 됩니다.

Core Data는 Persistence를 포함한 다양한 기능을 제공하는 Framework이다.

Persistence

Core Data abstracts the details of mapping your objects to a store, making it easy to save data from Swift and Objective-C without administering a database directly.

Core Data는 저장해야 할 객체를 추상화해서 database를 직접 다루지 않아도 데이터를 쉽게 저장할 수 있도록 도와줍니다.

Creating Core Data Model

문서를 참고해서 Core Data Model을 생성할 수 있습니다.

Data Model를 생성하고 나면 .xcdatamodeld 파일이 프로젝트명으로 만들어지는데, 원하는 데이터 모델 이름으로 변경할 수 있습니다.

다음으로, Entity를 추가합니다.
Entity는 데이터 모델에서 관리될 하나의 객체 model을 의미합니다.
Entity를 추가했으면 Entity의 속성(Attributes)을 추가합니다.

Creating and Saving Managed Objects

Core Data Model을 생성했으니, Core Data가 관리해주는 model object를 생성할 수 있습니다(Create NSManagedObject Subclass).

Subclass를 생성하기 전에, Entity에 해당하는 Class의 Codegen 옵션을 Manual/None으로 변경합니다.

  • Manual/None
  • Class Definition
  • Category/Extension

Create NSManagedObject Subclass...를 하면 Task+CoreDataClass.swift, Task+CoreDataProperties.swift 파일이 생성됩니다.
파일 안에 Model이 될 class 객체가 정의되어 있는 것을 확인할 수 있습니다.

Setting Up the Stack

AppDelegate를 보면 container가 설정되어 있는데, name은 .xcdatamodeld 파일명과 일치해야 합니다.

다음은 데이터 모델을 save, fetch하는 코드입니다.

// save data
func saveTask() {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    let entity = NSEntityDescription.entity(forEntityName: "Task", in: context)
    if let entity = entity {
        let task = NSManagedObject(entity: entity, insertInto: context)
        task.setValue(taskName, forKey: "name")
        task.setValue(Date(), forKey: "dueDate")
        do {
            try context.save()
            print("성공!")
            completionHandler?()
        } catch {
            print(error.localizedDescription)
        }
    }
}

// fetch data
func fetchTasks() {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    do {
        let task = try context.fetch(Task.fetchRequest()) as! [Task]
        taskData = task.map { $0.name ?? "no data"}
    } catch {
        print(error.localizedDescription)
    }
}

Core Data Manger

fetchTasks()처럼 데이터를 가져오는 함수를 정의해도 되지만, 다른 데이터 모델을 가져올 때도 반복될 코드를 줄이기 위해 CoreDataManager 파일을 생성해서 싱글톤으로 구현하는 것이 좋습니다.

class CoreDataManager {
    
    static let shared: CoreDataManager = CoreDataManager()
    
    let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
    lazy var context = appDelegate.persistentContainer.viewContext
    
    // generic fetch method
    func fetch<T: NSManagedObject>(request: NSFetchRequest<T>) -> [T] {
        do {
            let fetchResult = try self.context.fetch(request)
            return fetchResult
        } catch {
            print(error.localizedDescription)
            return []
        }
    }
}

// caller in ViewController
func fetchTasks() {
    let data = CoreDataManager.shared.fetch(request: Task.fetchRequest())
    taskData = data.map { ($0.name ?? "no data") }
}

Core Data Stack

Manage and persist your app’s model layer.

위에서 container를 설정해준 것은 Core Data Stack에 포함되는 것으로,
Core Data Stack은 Core Data에서 앱의 모델 레이어를 관리하는 핵심입니다.
NSManagedObjectModel, NSManagedObjectContext, NSPersistentStoreCoordinator object를 포함하고 있습니다.

Core Data Stack
You use an NSPersistentContainer instance to set up the model, context, and store coordinator simultaneously.

NSPersistentContainer

일반적으로 AppDelegate에 정의됩니다.

NSManagedObjectModel

The managed object model is the data model of the application. Even though Core Data isn't a database, you can compare the managed object model to the schema of a database, that is, it contains information about the models or entities of the object graph, what attributes they have, and how they relate to one another.

NSManagedObjectModel은 앱의 데이터 모델입니다. Core Data는 database가 아니지만 database의 스키마와 같다고 생각할 수 있습니다. model의 속성과 다른 model과의 관계를 포함하고 있습니다.

NSPersistentStoreCoordinator

As its name indicates, the NSPersistentStoreCoordinator object persists data to disk and ensures the persistent store(s) and the data model are compatible. It mediates between the persistent store(s) and the managed object context(s) and also takes care of loading and caching data. That's right. Core Data has caching built in.

The persistent store coordinator is the conductor of the Core Data orchestra. Despite its important role in the Core Data stack, we rarely interact with it directly.

NSPersistentStoreCoordinator는 disk에 data를 저장해서 data와 data model이 호환되도록 합니다. 또한 저장소(store)와 managed object context 간의 중재자 역할을 해서 caching data를 관리합니다.
NSPersistentStoreCoordinator는 Core Data 오케스트라의 지휘자와 같습니다.

NSManagedObjectContext

The NSManagedObjectContext object manages a collection of model objects, instances of the NSManagedObject class. It's perfectly possible to have multiple managed object contexts. Each managed object context is backed by a persistent store coordinator.

NSManagedObjectContext는 NSManagedObject class의 인스턴스를 관리합니다. 여러 개의 managed object contexts를 갖는 것도 물론 가능합니다. managed object contexts는 persistent store coordinator에 의해 지원됩니다.

References

documentation/coredata
creating_a_core_data_model
zeddios.tistory.com/coredata
hanulyun.medium.com/swift-coredata
core-data-stack

post-custom-banner

0개의 댓글