在我的应用程序上启用iCloud时,现有核心数据数据库无法上载到iCloud

时间:2014-05-11 13:43:08

标签: ios uitableview core-data icloud

我在App Store中有一个简单的应用程序,它是一个UITableView,由用户在一个模态调用的视图中填写一些UITextField来填充。用户按下保存并将所有内容保存到Core Data,并使用NSFetchedResultsControllers更新UITableView

我现在正在更新我的应用程序以引入iCloud同步(以及iPad版本)。

我是iCloud开发的新手,虽然我关注的帖子http://goddess-gate.com/dc2/index.php/post/452已经有几年了,但它主要适用于我。

问题

如果不进一步讨论其他问题,我现在遇到的一个问题是,如果我使用某些数据运行我的应用程序的App Store版本(它没有iCloud已启用),当我使用Xcode中的开发版本更新我的应用程序时,我希望我的原始数据仍然存在并因此上传到iCloud。

我的应用中没有复选框说没有上传,但我会接受。现在,问题是当我更新我的应用程序时,我从一个完全空白的数据库开始,虽然我怀疑我的代码现在实际显示数据只是一个问题,因为在我的设备的设置中,它显示了存储在iCloud中的9.7 KB数据(我确保在进行此测试之前删除了iCloud备份数据)。

我已经在Developer Portal中调整了我的App Id以包含iCloud并调整Xcode以包含它,同时在Developer中创建新的SSL证书并将新的配置文件重要到Xcode中。

更新:对我的应用进行了大量更改并删除旧代码

这是我的App Delegate persistentStoreCoordinator代码:(遵循汤姆的回答)

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

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Planner.sqlite"];
    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSDictionary *options = @{
                              NSMigratePersistentStoresAutomaticallyOption : @YES,
                              NSInferMappingModelAutomaticallyOption : @YES
                              };
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    NSPersistentStore *ps = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];

    NSFileManager *fm = [NSFileManager defaultManager];
    NSURL *url = [fm URLForUbiquityContainerIdentifier:nil];
    NSDictionary *iCloudOptions = @{
                              NSMigratePersistentStoresAutomaticallyOption : @YES,
                              NSInferMappingModelAutomaticallyOption : @YES,
                              NSPersistentStoreUbiquitousContentNameKey : @"EnvysStore"
                              };
    NSPersistentStore *store = [[_persistentStoreCoordinator persistentStores] firstObject];

    store = [_persistentStoreCoordinator migratePersistentStore:ps toURL:url options:iCloudOptions withType:NSSQLiteStoreType error:&error];

    return _persistentStoreCoordinator;
}

然而,在运行我的应用程序时,应用程序崩溃了:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'nil is not a valid persistent store' on the 

    store = [_persistentStoreCoordinator migratePersistentStore:ps toURL:url options:iCloudOptions withType:NSSQLiteStoreType error:&error];

问题

所以问题是,当我的应用程序商店版本的应用程序包含一些数据然后更新到此版本时,首先应用程序崩溃如上所述,但一旦我修复了,我希望我的现有数据被迁移到云端。

对此的任何指导都将受到大力赞赏!

1 个答案:

答案 0 :(得分:3)

  

如果不进一步讨论其他问题,我现在遇到的一个问题是,如果我使用某些数据运行我的应用程序的App Store版本(它没有iCloud已启用),当我使用Xcode中的开发版本更新我的应用程序时,我希望我的原始数据仍然存在,并因此上传到iCloud。

不是那么简单。 Core Data的iCloud集成使用事务日志来同步更改。每次保存对持久性存储文件的更改时都会生成事务日志。如果您只在现有数据存在时添加iCloud支持,则不会为该数据生成任何事务。没有事务日志,没有同步,您的数据仍然是本地的。

要将现有数据移至iCloud,您需要将持久存储迁移到新文件,在此过程中为所有现有数据生成事务。最简单的方法是调用[NSPersistentStoreCoordinator migratePersistentStore:toURL:options:withType:error:],它采用与添加持久存储文件时相同的选项。将本地商店迁移到新的支持iCloud的商店,如果一切正常,您将获得交易日志,数据将上传。

如果您的持久存储非常大,则可能需要使用自定义迁移代码。但大多数时候,内置的迁移方法都很好。