1

当用户升级或重新安装更新版本的 iOS 应用程序时,是否会调用任何委托方法?

我使用 Core Data 来缓存来自服务器的一些信息。当任何实体的schema发生变化时,我需要手动从模拟器中删除SQLite数据库,否则应用程序在启动时会崩溃,并出现错误“用于打开商店的模型与用于创建商店的模型不兼容。” 如果有任何应用程序升级的委托方法,则可以自动删除。

4

3 回答 3

4

您需要使用 CoreData 版本控制:

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CoreDataVersioning/Articles/Introduction.html

于 2012-10-12T17:52:16.917 回答
2

丹尼尔史密斯的答案是正确的,但我只想添加我的应用程序如何确定其已更新。我希望在默认值中保留一个“当前版本”字符串。当应用程序启动时,我将其与当前版本进行比较:

  • defaults 没有字符串 - 这是应用程序的第一次运行
  • 默认版本不同 - 用户更新了应用
  • 默认值相同 - 用户刚刚重新启动应用程序

有时很高兴知道以上内容。确保在设置标签后立即保存默认值并执行您想要的任何版本控制,因此崩溃不会让您再次执行此操作。

编辑:如果他的模型发生变化,如何不崩溃。我现在使用它,保留旧的存储库,并调整模型,在每次调整时它只是删除旧的(如果它无法打开它)并创建一个新的。这是以 Apple 的代码为模型的,但不确定我做了哪些更改。无论如何,如果模型发生变化,您都不会崩溃。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{   
    //LTLog(@"_persistentStoreCoordinator = %@", _persistentStoreCoordinator); 
    if (_persistentStoreCoordinator)
    {
        return _persistentStoreCoordinator;
    }
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *path = [[appDelegate applicationAppSupportDirectory] stringByAppendingPathComponent:[_dbName stringByAppendingPathExtension:@"SQLite"]];
    storeURL = [NSURL fileURLWithPath:path];

    BOOL fileExists = [manager fileExistsAtPath:path];
    if(!fileExists) {
        _didCreateNewRepository = YES;
    }
    if(_createNewRepository) {
        [manager removeItemAtURL:storeURL error:nil];
        if(fileExists) _didDestroyOldRepository = YES;
        _didCreateNewRepository = YES;
    }

    while(YES) {
        __autoreleasing NSError *error = nil;
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
        if ([_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {

            break;
        } else {
            _persistentStoreCoordinator = nil;
            [manager removeItemAtURL:storeURL error:&error];
            if(fileExists) {
                _didDestroyOldRepository = YES; // caller didn't want a new one but got a new one anyway (old one corrupt???)
                _didCreateNewRepository = YES;
            }
#ifndef NDEBUG
            LTLog(@"CORE DATA failed to open store %@: error=%@", _dbName, error);
#endif
            /*
             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.
             */
            //LTLog(@"Unresolved error %@, %@", error, [error userInfo]);
            //abort();
        }    
    }
    return _persistentStoreCoordinator;
}
于 2012-10-12T18:02:25.553 回答
1

关注博客很好:

http://blog.10to1.be/cocoa/2011/11/28/core-data-versioning/

于 2012-10-12T18:09:08.093 回答