티스토리 뷰
[Swift/iOS] CoreData 사용하기(2) - CoreData Stack 설정하기 From 공식문서
마들브라더 2023. 5. 5. 22:55! 공식문서를 참고한 글입니다.
https://developer.apple.com/documentation/coredata/setting_up_a_core_data_stack
https://modelinspring.tistory.com/90
[Swift/iOS] CoreData 사용하기(1) - 프로젝트 중간에 추가하기, Entity 만들기
CoreData를 사용하기 위해서는 프로젝트 생성시에 Use Core Data를 체크하면 되지만,프로젝트 중간에 CoreData를 추가하게 되었습니다.이 과정을 살펴보겠습니다. 프로젝트 중간에 CoreData 추가하기Data M
modelinspring.tistory.com
위 포스트에 이은 CoreData 두 번째 포스트입니다.
Core Data Stack
Core Data 모델 파일을 만든 후(https://modelinspring.tistory.com/90), 앱의 모델 레이어를 협력 지원하는 클래스를 설정합니다.
이 클래스들은 Core Data Stack이라고 합니다.
- NSManagedObjectModel의 인스턴스는 앱의 모델 파일을 나타내며, 앱의 타입, 프로퍼티들, 그리고 관계들을 설명합니다.
(구조체나 클래스처럼, 말 그대로 설명하는 그 자체) - NSManagedObjectContext의 인스턴스는 앱 타입들의 인스턴스의 변화들을 추적합니다.
(메서드? create, save, load) - NSPersistentStoreCoordinator의 인스턴스는 저장소로부터 앱 타입들의 인스턴스를 저장하고 가져옵니다.
(저장소 문지기) - NSPersistentContainer의 인스턴스는 model, context, 그리고 store coordinator를 한번에 설정합니다.
(이 모든 것을 포함하는 것)
Persistent Container 초기화 (Initialize a Persistent Container)
일반적으로, 앱이 시작되는 동안에 코어데이터는 초기화됩니다.
persistent container를 delegate안에서 처음 사용되기 전까지, 인스턴스화를 지연시키기 위해서 지연 저장 프로퍼티(lazy var)로 만들겠습니다.
만약 프로젝트를 처음 생성할 때, Use Core Data 체크 박스를 선택했다면, 아래 템플릿은 자동으로 AppDelegate에 포함됩니다.
(https://modelinspring.tistory.com/90 와 중복되는 내용)
1. NSPersistentContainer를 지연 저장 프로퍼티로 선언합니다.
2. persistent container 인스턴스를 생성하고, data model 파일 이름을 초기화 하기 위해서 인자로 전달합니다.
3. 다른 persistent 저장소를 load, 이 콜은 만약 저장소가 없다면 저장소를 생성합니다.
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 프로퍼티들의 model, context, 그리고 store coordinator 인스턴스들에 대한 참조를 보관합니다.
이제 유저 인터페이스에 container에 참조를 전달할 수 있습니다.
View Controller에 Persistent Container 전달하기
(Pass a Persistent Container Reference to a View Controller)
앱의 root 뷰 컨트롤러에 Core Data를 import 합니다.
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.
}
}
AppDelegate에 돌아가서,
didFinishLaunchingWithOptions메서드에 window의 root 뷰컨트롤러를 앱의 root 뷰 컨트롤러로 다운캐스팅 합니다.
root 뷰 컨트롤러의 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 // 앱의 컨테이너에 persistente Container 전달
}
return true
}
...
}
추가적인 뷰 컨트롤러들에 persistent container를 전달하기 위해서,
각 뷰 컨트롤러에 반복해서 container 변수를 생성하고,
이전 뷰 컨트롤러의 prepare 메서드에서 값을 설정합니다.
(스토리보드 기반의 코드)
class ViewController: UIViewController {
...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nextVC = segue.destination as? NextViewController {
nextVC.container = container
}
}
}
여기서 드는 의문은 '꼭 한번 루트뷰에서 설정한 변수를 계속해서 전달하면서 사용해야하는것인가' 입니다.
실제 앱에서 루트뷰가 바뀔 때는 어떻게 처리해야할까요?
그냥 헬퍼 클래스 하나 만들어서 쓰면 어떨까 싶습니다.
(이후 앱에서는 CoreData를 관리하는 Singleton 패턴 매니저를 만들어서 사용하게 되었습니다)
Persistent Container 서브클래스 만들기(SubClass the Persistent Container)
NSPersistentContainer는 서브클래스 되도록 의도되었습니다.
서브클래스는 data의 subset을 반환하는 함수나 disk에 data를 유지하는 함수같은 코어데이터 관련 코드를 넣는 곳입니다.
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)")
}
}
}
위의 예시 코드는
오직 context에 변화가 있을 때 context를 저장하여 성능을 향상시키도록
컨테이너에 saveContext 메서드를 추가했습니다.
모델 레이어를 자체 프레임 워크로 넣는 경우,
NSPersistentContainer subclass는 모델 파일을 bundle안에 놓습니다.
참고
https://developer.apple.com/documentation/coredata/setting_up_a_core_data_stack
https://zeddios.tistory.com/987
'programming > Swift' 카테고리의 다른 글
[Swift/iOS] CoreData 사용하기(4) - 속성값 유무에 따른 데이터 저장, 속성의 optional 타입 (0) | 2023.05.06 |
---|---|
[Swift/iOS] CoreData 사용하기(3) - 데이터 저장하기, 데이터 불러오기 기초 (0) | 2023.05.06 |
[Swift/iOS] CoreData 사용하기(1) - 프로젝트 중간에 추가하기, Entity 만들기 (0) | 2023.05.05 |
[Swift/iOS] 메모리 안전성 Memory Safety From 공식문서(2) (0) | 2023.05.05 |
[Swift/iOS/디자인패턴] 퍼사드 Facade 패턴 (0) | 2023.05.03 |
- Total
- Today
- Yesterday
- unowned
- 토큰저장
- 회원가입
- ASAuthorizationAppleIDCredential
- 클로저 축약
- 강한 참조 순환
- SWIFT
- 캡쳐리스트
- 클로저 강한 참조
- escaping closrue
- 디자인패턴
- Persistent Container
- 클로저표현
- Core Data Stack
- ios
- CoreData
- core data
- autoclosure
- 클로저
- 강한참조순환
- context
- 메모리 안정성
- identity Token
- inout 파라미터 메모리 충돌
- Entity
- authorizationCode
- weak
- object
- 자동클로저
- Delegate 패턴
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |