[Core Data] Light Weight Migration의 접근 방식

14347 단어 SwiftCoreDataiOS
개시하다
개인이 발표한 애플리케이션Core DataCloudKit 사용은 기능 추가Core Data에 따라 수정됐다.코어데이터의 이전은 문서와 기사만 읽으면 그렇게 어렵지 않지만, 잘 이해하고 싶은 기사를 정리했습니다.
컨디션
Xcode 13.2.1
Swift 5.5.2
문서 읽기
문서: Core Data - Light Weight Migration
Data Migration의 종류
1. Light Weight (automatic) Migration
Light Weight(자동) 마이그레이션을 통해 적용된 변경 사항에 따라 데이터 모델을 업데이트할 수 있습니다.
2. Heavy Weight (manual) Migration
데이터 모델이 자동 마이그레이션 기능을 초과하는 경우 Heavy Weight(수동) 마이그레이션을 사용합니다.
Light Weight Migration
문서: Using Lightweight Migration
Core Data는 일반적으로 경량 마이그레이션이라고 불리는 자동 데이터 마이그레이션을 수행할 수 있습니다.경량 이동은 이동원과 이동 목적지의 관리 대상 모델의 차이에 따라 데이터 이동을 추측하여 진행된다.
■ CoreData는 다음과 같은 조건에서 지속성 실체와 속성에 대한 분석을 통해 추론적 매핑 모델을 생성하고 데이터 이동을 진행한다.
  • 속성(Attribute)의 추가
  • 속성(Attribute)의 삭제
  • 속성(Attribute)을 옵션으로 변경
  • 속성(Attribute)을 비선택적(기본값)으로 변경
  • 솔리드 속성의 이름바꾸기
  • ■ 실체 또는 속성의 명칭이 변경될 경우 변경 대상 모델의 명칭 변경 식별자를 원 모델의 대응하는 속성이나 실체의 명칭으로 설정하여 데이터 이동을 진행한다.
    ■ 새로운 관계를 추가하거나 기존 관계를 삭제할 수 있다.또한 속성과 마찬가지로 이름 바꾸기 식별자를 사용하여 관계의 이름을 변경할 수도 있습니다.또한 관계를 일대일에서 다대일로 바꾸거나 비순서 유형에서 순서 유형으로 바꿀 수 있다(반대로도 마찬가지).
    ■ 계층에서 엔티티를 추가, 제거, 이름을 바꿀 수 있습니다.새 부모 솔리드 또는 하위 솔리드를 작성하고 속성을 솔리드 레이어로 위아래로 이동할 수도 있습니다.솔리드는 계층에서 이동할 수 있습니다.그러나 솔리드 레이어는 결합할 수 없습니다.만약에 기존의 두 실체가 원천적으로 공통된 부모를 공유하지 않는다면 이런 실체는 목적지에서 공통된 부모를 공유할 수 없다.
    Light Weight Migration이 가능한지 확인
    실제 이전 작업을 하지 않고 코어데이터가 전이원 모델과 전이목적지 모델 사이의 매핑 모델을 추측할 수 있는지 사전에 판단하고자 하는 경우NSMappingModelinferredMappingModel(forSourceModel:destinationModel:) 방법을 사용하여 코어데이터가 제작될 수 있는 상황에서 추론된 모델을 얻을 수 있다.
    Light Weight Migration 구현 방법addPersistentStore(ofType: configurationName: at: options:)를 사용하여 자동 경량 전송을 요청합니다.또한 매개 변수를 통해 전달되는 옵션은 NSMigratePersistentStoresAutomaticallyOptionNSInferMappingModelAutomaticallyOption 두 키에 대응하는 값을 진으로 설정합니다.
    let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
    let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
    do {
        try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: options)
    } catch {
        fatalError("Failed to add persistent store: \(error)")
    }
    
    이러한 설정을 통해 Core Data는 영구 스토리지가 현재 모드와 일치하지 않음을 감지하면 가벼운 마이그레이션을 시도합니다.
    이상은 문서에서 확인한 내용입니다.
    새 데이터 모델 추가 및 전환
    데이터 모델 추가
    Add Model Version에서 간단히 추가 가능

    Version name도 초기 값을 그대로 사용하며 Based on model은 현재 Data Model을 지정합니다.

    이렇게 새로운 데이터 모델이 추가되었습니다.

    데이터 모드 전환Model Version Current 새로 추가된 데이터 모델

    초록색 로고가 추가된 DataModel이 있으면 OK입니다.

    새로 추가된 데이터 모델 수정

    👇이번에 이렇게 Enity를 추가했습니다.

    추가, 수정된 Enity 클래스 생성
    선택 dataModelEditor->Create NSManagedObject Subclass Enity 클래스 자동 생성
    그때 추가된 EnityManual/None로 바꾸는 거 잊지 마세요.💡

    설치(필요 없음)
    우선 현황CoreDataManager 중의 상황을 확인한다
    CoreDataManager
    final class CoreDataManager: CoreDataProtocol {
        static let shared = CoreDataManager()
        
        private init() { }
        
        // アプリケーション内のオブジェクトとデータベースの間のやり取りを行う
        lazy var persistentContainer: NSPersistentCloudKitContainer = {
            let container = NSPersistentCloudKitContainer(name: "PadelLessonLog")
            container.loadPersistentStores(completionHandler: { _, error in
                if let error = error as NSError? {
                    // リリースビルドでは通っても何も起きない
                    assertionFailure("Unresolved error \(error), \(error.userInfo)")
                }
            })
            return container
        }()
        
        // persistentContainerデータベース情報を表す
        // 管理オブジェクトコンテキスト。NSManagedObject 群を管理するクラス
        var managerObjectContext: NSManagedObjectContext {
            persistentContainer.viewContext
        }
    }
    
    프로젝트를 새로 만들 때 옵션으로 코어데이터를 추가하면AppDelegate 일부 코드가 추가되지만 그 부분을 CoreDataManager로 옮깁니다.
    Light Weight Migration이 가능한지 확인(※ 하지 않아도 됨)
    우선 맵 모형을 만들 수 있는지 확인해 보자.
    CoreDataManager
        var checkLightWeightMigration: NSMappingModel {
            let subdirectory = "PadelLessonLog.momd"
            let sourceModel = NSManagedObjectModel(contentsOf: Bundle.main.url(forResource: "PadelLessonLog", withExtension: "mom", subdirectory: subdirectory)!)!
            let destinationModel = NSManagedObjectModel(contentsOf: Bundle.main.url(forResource: "PadelLessonLog 2", withExtension: "mom", subdirectory: subdirectory)!)!
            do {
                return try NSMappingModel.inferredMappingModel(forSourceModel: sourceModel, destinationModel: destinationModel)
            } catch {
                fatalError("migrationCheck error \(error)")
            }
        }
    
    CoreDataManager👆적당한 곳print(CoreDataManager.shared.checkLightWeightMigration)에 디버깅 확인을 적었습니다.

    비슷한 게 보여서 확인했어요Light Weight Migration. 될 것 같아요.
    Light Weight Migration 설치(※ 필요 없음)
    우선 현재 상황(기본값)의NSMigratePersistentStoresAutomaticallyOptionNSInferMappingModelAutomaticallyOption를 확인하고 싶습니다.
    CoreDataManager
    let container = NSPersistentCloudKitContainer(name: "PadelLessonLog")
    print(container.persistentStoreDescriptions.count)
    print(container.persistentStoreDescriptions.first?.shouldMigrateStoreAutomatically)
    print(container.persistentStoreDescriptions.first?.shouldInferMappingModelAutomatically)
    
    좀 무리print지만 디버깅 준비할게요.

    둘 다 true에 설정되어 있어요.❗️
    수정 없이 마이그레이션할 수 있을 것 같습니다.
    끝말
    많이 썼지만 결과적으로 코어데이터 마이그레이션은 새로운 데이터 모델을 만들고 전환하기만 하면 됩니다.👏
    하지만 마이그레이션에 실패하고 중요한 데이터가 사라진다면 큰 문제이기 때문에 이 근처에서 정리하고 신중하게 작업하고 싶어요.

    여기 기사는 참고할 만한 부분이 있어요.💡
    Core Data는 먼저 애플리케이션 번들 내에서 영구 스토리지 모드에서 현재 번들 모드로 매핑된 모델을 검색하고 마이그레이션을 수행합니다.사용자 정의 매핑 모델을 찾을 수 없으면 Core Data에서 Lightweight 마이그레이션을 시도합니다.어떤 형태든 옮길 수 없는 경우에는 예외적으로 투척된다.
    참고 자료

    좋은 웹페이지 즐겨찾기