새로운 프로젝트를 만들고자 한다면, 프로젝트 생성 시 Use core Data 항목에 체크를 하고 프로젝트를 생성하면 자동으로 세팅된다. 예시로 사용할 CoreDataTest 앱을 생성해보자.
생성된 프로젝트 파일을 다르면 이전까지 만들었던 템플릿 과는 다름을 알 수 있다. CoreDataTest.xcdatamodeld 에 앞으로 우리가 사용할 데이터와 구조를 저장한다.
AppDelegate.swift 파일에도 Core Data를 사용하지 않을 때와는 달리 추가적인 코드가 작성되어 있다. 주석을 지운 모습은 다음과 같다.
persistentContainer 변수에 붙은 lazy 키워드를 사용해서 변수를 생성하면, 프로그램이 시작할 때 메모리를 할당해주는 것이 아니라 그 변수가 필요할 때 변수에 메모리를 할당해주는 효과가 있다. NSPersistentContainer가 기본적으로 우리가 데이터를 저장하는데 쓸 컨테이너이며 기본 persistent container로 SQLite를 사용한다. 그럼에도 불구하고, 이름이 SQLite 가 아니라 persistentContainer인 이유는 persistent data를 다루는 데 있어 XML, SQLite 등 다양한 옵션을 사용할 수 있기 때문이다.
saveContext() 함수의 context변수를 이용해서 persistentContainer에 데이터를 저장/업데이트하게 된다.
import CoreData
func applicationWillTerminate(_ application: UIApplication) {
self.saveContext() // 추가
}
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "CoreDataTest")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
만약 Core Data 체크박스를 체크하지 않은 채로 프로젝트를 생성하고, 나중에 Core Data를 추가하고 싶다면, 이 코드를 AppDelegate.swift에 추가해주고, Data Model파일을 생성해야 한다.
여기서 우리가 생성한 Data Model의 이름과, AppDelegate파일의 persistentContainer 변수 선언에서, 컨테이너의 이름을 동일하게 해주어야 한다.
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "(내가 생성한 데이터 모델 이름)")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
이렇게 하면, Core Data 체크박스에 체크한 프로젝트와 완전히 동일하게 된다.
DataModel 파일에서는 엔티티(Entity)와 각 엔티티에 따른 속성(Attribute)을 추가할 수 있다. 아래 사진은 Item이라는 엔티티에 title과 done이라는 속성을 추가한 것이다. 엔티티를 클래스에 대응시키면, 속성은 프로퍼티에 대응된다고 이해하자. 하나의 엔티티는 하나의 테이블처럼 사용한다.
Entity의 Attribute Inspector에서도 엔티티의 이름과 다른 속성들을 설정할 수 있다. 프로퍼티를 생성하면, 타입을 정할 수 있으며, 기본값으로 Optional이 체크되어 있다. 반드시 존재해야 하는 값이라면 Optional의 체크박스를 해제해 주어야 한다.
그리고 엔티티에서 클래스의 모듈을 Current Product Module로 선택해주어야한다. Core Data 프로젝트가 점점 복잡해지면, 특히 앱이 멀티스레딩을 요구하게 될 때 이 옵션을 체크하지 않는다면 에러가 발생할 수 있기 때문이다.
또한 엔티티의 속성에서 Codegen이라는 속성을 볼 수 있다. Manual/None, Class Definition, Category/Extension 세 가지의 옵션이 있다.
기본값은 Class Definition이다 우리가 만든 엔티티와 속성을 클래스와 프로퍼티를 만든 것처럼 사용할 수 있도록 해준다. 클래스가 생성되지만, Xcode상의 파인 터에는 생성되지 않고, 특정 위치에 생성된다. 실제로 생성된 클래스의 모습이다.
Category/Extension 옵션을 선택하면 엔티티와 동일한 이름을 가진 클래스를 직접 생성해 주어야하고, 엔티티와 동일한 이름을 가진 클래스를 Xcode에서 자동으로 연결해준다.
Manual/None 옵션은 아무것도 생성해주지 않고, 자동으로 연결해주지 않기때문에 사용자가 모든 것을 직접 해야 한다.
가장 중요한 두가지를 다시 기억하면,
NSPersistentContainer를 통해 우리가 만든 DataModel의 이름을 사용해서 container를 만들고 이 container는 SQLite를 사용하며, 우리가 데이터를 저장할 장소이다.
context는 우리가 원하는 데이터 포맷을 만들 때까지 데이터를 저장하고 업데이트하고, container에 데이터를 저장할 때 사용한다.
이 두가지가 Core Data가 어떻게 동작하는지에 대한 핵심이다.
'iOS > 데이터베이스 조작' 카테고리의 다른 글
Core Data: Read, Update, Delete (0) | 2022.01.31 |
---|---|
CoreData를 사용해서 데이터 저장하기(Create) (0) | 2022.01.30 |
Persistent Data Storage (0) | 2022.01.29 |
Userdefaults로 데이터 Persistency 유지하기 (0) | 2022.01.27 |
Firebase를 이용한 앱개발2: 프로젝트에 Firebase추가하기 (0) | 2022.01.14 |