Just a Computer Graphics Studio & My Life

為了儲存更多的資料,我們難免會在Core Data上增加Attribute,甚至為了方便管理資料庫,我們會分割單一Table為多個Table,而最簡單的Core Data Lightweight Migration,只要在某個method中加入幾行程式碼即可運作。

– (NSPersistentStoreCoordinator *)persistentStoreCoordinator


Core Data Lightweight Migration基本步驟:

  • 點選.xcdatamodeld檔
  • Editor -> Add Model Version 增加版本
  • 命名下一個版本,確認後產生.xcdatamodel檔
  • File Inspector -> Current 選擇版本
  • 增加幾行程式碼如下

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSURL *storeUrl = [NSURL fileURLWithPath: [self persistentStoreFilePath]];

    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    //~~~
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
    //~~~
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.

         Typical reasons for an error here include:
         * The persistent store is not accessible
         * The schema for the persistent store is incompatible with current managed object model
         Check the error message to determine what the actual problem was.
         */
        NSLog(@"CoreData : Unresolved error %@, %@", error, [error userInfo]);
    }

    return persistentStoreCoordinator;
}

節錄這幾行程式碼:

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
        NSLog(@"CoreData : Unresolved error %@, %@", error, [error userInfo]);
    }

若沒有加入上述程式碼,編譯執行時就會出現錯誤訊息:

2013-02-08 13:58:44.797 HouseBook[1329:707] CoreData : Unresolved error Error Domain=NSCocoaErrorDomain Code=134100 "The operation couldn’t be completed. (Cocoa error 134100.)" UserInfo=0x3e1890 {metadata={type = immutable dict, count = 7,
entries =>
	2 : {contents = "NSStoreModelVersionIdentifiers"} = {type = immutable, count = 1, values = (
	0 : {contents = ""}
)}
	4 : {contents = "NSPersistenceFrameworkVersion"} = {value = +386, type = kCFNumberSInt64Type}
	6 : {contents = "NSStoreModelVersionHashes"} = {type = immutable dict, count = 2,
entries =>
	0 : {contents = "NoteRent"} = {length = 32, capacity = 32, bytes = 0xc25eccf34c5041729220e5e97f28138e ... 60ca45c7ef57858e}
	1 : {contents = "NoteBuy"} = {length = 32, capacity = 32, bytes = 0x5656aab321e1527c2aa6914cce218b5c ... 3374b82d6a962dcb}
}

	7 : {contents = "NSStoreUUID"} = {contents = "C19D3598-CBCE-4F76-BBC9-98BD2D4C325F"}
	8 : {contents = "NSStoreType"} = {contents = "SQLite"}
	9 : {contents = "_NSAutoVacuumLevel"} = {contents = "2"}
	10 : {contents = "NSStoreModelVersionHashesVersion"} = {value = +3, type = kCFNumberSInt32Type}
}
, reason=The model used to open the store is incompatible with the one used to create the store}, {
metadata =     {
NSPersistenceFrameworkVersion = 386;
NSStoreModelVersionHashes =         {
NoteBuy = ;
NoteRent = ;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers =         (
""
);
NSStoreType = SQLite;
NSStoreUUID = "C19D3598-CBCE-4F76-BBC9-98BD2D4C325F";
"_NSAutoVacuumLevel" = 2;
};
reason = "The model used to open the store is incompatible with the one used to create the store";
}

順利的話,錯誤訊息就不會再出現,而原本的資料會重新出現在程式中。

Core Data Lightweight Migration能夠作用在這幾個更動情況:

  • Adding a new attribute/property to an entity.
  • Renaming of an entity or an attribute/property if the ‘Renaming Identifier’ is given.
  • Changing an attribute/property to optional or non-optional, whether it requires a value on creation.

若新版本的.xcdatamodel較為複雜,就需要增加Mapping Model,其副檔名為.xcmappingmodel,描述舊版本與新版本之間Entity和Attribute的對應關係,接著要在程式碼中檢查版本差異,進行Core Data Migration

參考:Simple Core Data Model MigrationCore Data Migration – Standard Migration Part 2Working with Core Data: Schema Versioning and Lightweight MigrationsCore Data Model Versioning and Data Migration

Advertisements

發表留言

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

標籤雲

%d 位部落客按了讚: