- if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl
- options:nil error:&error]) {
- // Update to handle the error appropriately.
- NSLog(@"[persistentStoreCoordinator] Unresolved error %@, %@", error, [error userInfo]);
- exit(-1); // Fail
- }
這個問題容易理解,我們就是通過一個ManagerdObjectModel(具體對應xcode裏面的xxx.xcdatamodel文件,下面簡稱mom)來訪問具體的存儲數據,這裏是xxx.sqlite文件,mom有一個hash table保存這個sqlite文件中的所有數據類型,版本等,當發現不匹配了就返回錯誤,如果想簡單起見,可以在這裏刪除舊的數據,重新load一遍:
- if(![fileManager removeItemAtPath:storePath error:&error]){
- [NSException raise:NSInternalInconsistencyException format:@"Failed to remove ecrupt sqlite file. Location:%@", NSStringFromSelector(_cmd)];
- }
- NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"im" ofType:@"sqlite"];
- if (defaultStorePath) {
- [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
- }
- if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl
- options:options error:&error]){
- [NSException raise:NSInternalInconsistencyException format:@"Failed to addPersistentStoreWithType. Location:%@", NSStringFromSelector(_cmd)];
- }
如果CoreData的實體數據發生下面幾種變化的情況:
- 增加一個屬性
- 必選的(non-optional)屬性變成可選的(optional)
- 可選的(optional)屬性變成了必選的(non-optional),並且定義了默認值
可以通過簡單的方法(輕量級遷移)使得我們可以直接使用新的mom文件來訪問舊的sqlite文件,既在打開存儲文件的之前打開自動遷移:
- NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],
- NSMigratePersistentStoresAutomaticallyOption,
- [NSNumber numberWithBool:YES],
- NSInferMappingModelAutomaticallyOption, nil];
- NSError *error;
- if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
- configuration:nil
- URL:storeUrl
- options:options error:&error]) {
- // Update to handle the error appropriately.
- exit(-1); // Fail
- }
- - (NSManagedObjectModel *)managedObjectModel {
- if (managedObjectModel != nil) {
- return managedObjectModel;
- }
- NSString *path = [[NSBundle mainBundle] pathForResource:@"xxx 2" ofType:@"mom" inDirectory:@"xxx.momd"];
- NSURL *momURL = [NSURL fileURLWithPath:path];
- return managedObjectModel;
- }
- - (NSManagedObjectModel *)managedObjectModel {
- if (managedObjectModel != nil) {
- return managedObjectModel;
- }
- NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"xxx" withExtension:@"momd"];
- managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
- return managedObjectModel;
- }
需要在加載mom文件之後,打開存儲文件之前調用如下代碼:
NSEntityDescription *automobile = [[destinationModel entitiesByName] objectForKey:@"Automobile"]; [automobile setRenamingIdentifier:@"Car"]; NSPropertyDescription *paintColor = [[automobile attributesByName] objectForKey:@"paintColor"]; [paintColor setRenamingIdentifier:@"color"];
或者可以直接在mom編輯器裏面設置,請參考
其他的變化我們需要使用Mapping的機制來完成數據的遷移,這裏有兩種方式可以選擇(參考):
- 默認遷移
- 自定義遷移
默認遷移只需要做兩步,第一步在前面已經做過了,就是在輕量級遷移中設置的參數,第二步需要一個map文件,生成方法可以參考,如果不生成該文件,在訪問存儲文件時成功,但在訪問數據的時候會發生異常;
自定義遷移需要手動控制各個實體,字段的遷移方式,我還沒有試過