소피it블로그
[Core Data] 코어 데이터 스택 셋업하기 본문
https://developer.apple.com/documentation/coredata/setting_up_a_core_data_stack
앱의 객체들을 관리하고 저장해주는 클래스를 셋업해보자.
1. 개요
데이터 모델 파일을 생성한 후에 앱의 모델 계층을 통합적으로 지원하는 클래스들을 생성하라. 이 클래스들을 통틀어 Core Data stack 이라고 부른다.
- NSManagedObjectModel의 인스턴스는 앱의 타입, 프라퍼티, 관계를 묘사하는 모델 파일을 나타낸다.
- NSManagedObjectContext의 인스턴스는 앱의 타입의 인스턴스들의 변화를 감지한다.
- NSPersistentStoreCoordinator의 인스턴스는 앱의 타입의 인스턴스를 스토어로부터 저장하고 페치한다.
- NSPersistentContainer는 모델, 컨텍스트, 스토어 코디네이터를 모두 한 번에 셋업한다.
2. Persistent Container 초기화하기
코어 데이터는 대개 앱이 시작할 때 초기화한다. persistent container를 lazy 변수로 생성함으로써 앱의 delegate에서 처음 사용될 때로 초기화를 연기할 수 있다.
엑스코드 프로젝트를 새로 생성할 당시에 Core Data에 체크를 했으면, AppDelegate 내부에 이 셋업 코드가 자동적으로 포함된다.
- NSPersistentContainer 타입의 lazy 변수를 선언하기
- 데이터 모델 파일명을 이니셜라이저에 전달함으로써 persistent container 인스턴스를 생성하기
- persistent store가 있다면 로딩하기. 없는 경우 새로 생성함
class AppDelegate: UIResponder, UIApplicationDelegate {
...
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores { description, error in
if let error = error {
fatalError("Unable to load persistent stores: \(error)")
}
}
return container
}()
...
}
persistent container는 한 번 생성된 후에는 모델, 컨텍스트, 스토어 코디네이터 인스턴스들에 대한 레퍼런스를 각각 managedObjectModel, viewContext, persistentStoreCoordinator 프라퍼티에 각각 가진다.
이제 유저 인터페이스의 컨테이너에 레퍼런스를 전달할 수 있다.
3. Persistent Container Reference를 뷰컨트롤러로 전달하기
앱의 루트 뷰 컨트롤러에 Core Data를 임포트하고 persistent container의 레퍼런스를 홀드할 변수를 생성하라.
import UIKit
import CoreData
class ViewController: UIViewController {
var container: NSPersistentContainer!
override func viewDidLoad() {
super.viewDidLoad()
guard container != nil else {
fatalError("This view needs a persistent container.")
}
// The persistent container is available.
}
}
앱의 델리게이트로 돌아가보자. application(_:didFinishLaunchingWithOptions:) 내부에서 앱 윈도우의 rootViewController를 앱의 루트 뷰 컨트롤러 타입으로 다운캐스팅하라. 이 레퍼런스에서 루트 뷰 컨트롤러의 container 프라퍼티를 persistent container로 세팅하라.
class AppDelegate: UIResponder, UIApplicationDelegate {
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let rootVC = window?.rootViewController as? ViewController {
rootVC.container = persistentContainer
}
return true
}
...
}
persistent container를 추가적인 뷰 컨트롤러에 패스하기 위해서는 각 뷰 컨트롤러에서 container 변수를 반복하여 생성하고, 그 값을 이전 뷰 컨트롤러의 prepare(for:sender:)에 세팅하라.
class ViewController: UIViewController {
...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nextVC = segue.destination as? NextViewController {
nextVC.container = container
}
}
}
4. Persistent Container 서브클래싱하기
NSPersistentContainer는 서브클래스되도록 의도되었다. 서브클래스는 데이터의 subset을 리넡하고 디스크에 데이터를 저장하게 호출하는 함수와 같은, 코어 데이터와 관련된 코드를 저장하기에 편리한 장소이다.
import CoreData
class PersistentContainer: NSPersistentContainer {
func saveContext(backgroundContext: NSManagedObjectContext? = nil) {
let context = backgroundContext ?? viewContext
guard context.hasChanges else { return }
do {
try context.save()
} catch let error as NSError {
print("Error: \(error), \(error.userInfo)")
}
}
}
위의 예시에서는 컨테이너에 saveContext 함수를 추가함으로써 변화가 있을 경우에만 컨텍스트를 저장하도록 하여 성능을 향상시킨다.
'개발_iOS > 데이터 관리' 카테고리의 다른 글
[Core Data] 데이터 모델링하기 (0) | 2022.08.17 |
---|---|
[Core Data] 코어 데이터 정리 (0) | 2022.08.17 |
[Foundation] NSCoder 정리 (1) | 2022.08.17 |
[iOS 개발] 데이터 영속성 문제 해결 방안 정리 (0) | 2022.08.17 |
[Foundation] UserDefaults 정리 (1) | 2022.08.16 |