【问题标题】:Move local Core Data to iCloud将本地核心数据移动到 iCloud
【发布时间】:2014-10-07 09:12:16
【问题描述】:

如何在已经使用本地存储核心数据的应用中启用 iCloud 核心数据?

我尝试在我的持久存储选项中使用NSPersistentStoreUbiquitousContentNameKey。不幸的是,此选项启用 iCloud,但不会将任何本地数据传输到 iCloud。我似乎也无法让migratePersistentStore:toURL:options:withType:error: 工作。我提供了持久存储、它的 URL、iCloud 选项等,它仍然不会将现有的本地数据迁移到 iCloud。以下是我使用该方法的方式:

- (void)migratePersistentStoreWithOptions:(NSDictionary *)options {
    NSError *error;
    self.storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.sqlite", self.SQLiteFileName]];

    NSPersistentStore *store = [self.persistentStoreCoordinator migratePersistentStore:self.persistentStoreCoordinator.persistentStores.firstObject toURL:self.storeURL options:options withType:NSSQLiteStoreType error:&error];
    if (store) NSLog(@"[CoreData Manager] Store was successfully migrated");
    else NSLog(@"[CoreData Manager] Error migrating persistent store: %@", error);
} 

本地存储与 iCloud 存储保持分离。如果可能,我想将本地核心数据移动到 iCloud,而无需手动传输每个实体。

有什么想法吗?我可以找到很多关于 iCloud 移回本地存储的文章、教程和帖子 - 但我想 本地存储移动到 iCloud

【问题讨论】:

  • “我似乎也无法让 migratePersistentStore:toURL:options:withType:error: 工作。” 具体来说,它在什么方面不起作用?
  • @TomHarrington 查看我最近的编辑。当我调用该方法并指定存储及其 URL 时,没有任何内容被移动 - 本地存储保持不变,而 iCloud 存储保持为空。

标签: ios objective-c cocoa-touch core-data icloud


【解决方案1】:

这就是你需要做的事情

  1. 创建本地 NSPersistentStoreCoordinator
  2. 将现有的持久存储添加到该协调器并存储对这个新返回的存储的引用。
  3. 调用方便的 migratePersistStore:... 提供来自 #2 的存储、文档目录中具有不同文件名的存储的 URL 以及包括 NSPersistentStoreUbiquitousContentNameKey 键在内的所有重要选项。

这是代码,内嵌注释。

NSURL *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];

//This is the path to the new store. Note it has a different file name
NSURL *storeURL = [documentsDirectory URLByAppendingPathComponent:@"TestRemote.sqlite"];

//This is the path to the existing store
NSURL *seedStoreURL = [documentsDirectory URLByAppendingPathComponent:@"Test.sqlite"];

//You should create a new store here instead of using the one you presumably already have access to
NSPersistentStoreCoordinator *coord = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];

NSError *seedStoreError;
NSDictionary *seedStoreOptions = @{ NSReadOnlyPersistentStoreOption: @YES };
NSPersistentStore *seedStore = [coord addPersistentStoreWithType:NSSQLiteStoreType
                                                   configuration:nil
                                                             URL:seedStoreURL
                                                         options:seedStoreOptions
                                                           error:&seedStoreError];

NSDictionary *iCloudOptions = @{ NSPersistentStoreUbiquitousContentNameKey: @"MyiCloudStore" };
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

//This is using an operation queue because this happens synchronously
[queue addOperationWithBlock:^{
    NSError *blockError;
    [coord migratePersistentStore:seedStore
                            toURL:storeURL
                          options:iCloudOptions
                         withType:NSSQLiteStoreType
                            error:&blockError];

    NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
    [mainQueue addOperationWithBlock:^{
        // This will be called when the migration is done
    }];
}];

请注意,执行此迁移后,您需要使用新 URL 配置您与 MOC 一起使用的持久性存储,并始终在 NSPersistentStoreUbiquitousContentNameKey 键中包含上面的 iCloudOptions。

这是基于Apple's documentation

完成后,您应该会在模拟器文件夹 (~/Library/Application Support/iPhone Simulator/...) 中的 Documents 文件夹中看到一个新文件夹,标记为 CoreDataUbiquitySupport。你的 iCloud 同步 sqlite 存储在深处嵌套。

多田!


编辑:哦,请确保您已创建 iCloud 权利并将其包含在您的捆绑包中。您应该可以在 Xcode 中完成所有这些操作,但您也可以在开发门户上对其进行更新。

【讨论】:

  • 但是对于设备,我看不到它正在工作。我应该如何检查文件是否移动到了 iCloud?
  • 在 iCloud 同步后,您应该能够在登录到同一 iCloud 帐户的另一台设备上运行该应用程序,并通过尝试使用相同的 URL 打开文件来查看文件是否被复制。如果您想查看 iPhone 文件系统中的实际文件,您需要越狱设备,通过 ssh 进入设备并查看应用程序的文件夹。我认为与测试结果相比有点矫枉过正。
  • @Acey 这是一个很好的答案。但是,每次我的应用程序启动时,如何防止应用程序运行呢?有没有办法只运行一次,或者我应该只检查一个布尔标志并在第一次迁移完成时设置它:[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"migratedToiCloud"];
  • 好吧,我想在迁移完成后你可以删除旧的数据库文件。检查启动时是否存在以确定是否需要迁移。
  • 如果我也想进行架构迁移怎么办?添加种子存储时,Core Data 不会抱怨 momd 不同吗?或者它也可以进行轻量级迁移?
【解决方案2】:

看看这个示例应用程序,其中包含将本地核心数据存储迁移到 iCloud 并再次迁移回来的代码。最好阅读相关文档并在您的环境中构建示例应用程序以使它们工作,一旦它们工作,然后尝试重构您的代码以使用类似的方法。

请随时给我发送电子邮件以获取更多帮助。很抱歉在这里没有给你答案,但这可能是一个相当复杂的问题。

http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/

【讨论】:

    猜你喜欢
    • 2012-09-27
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 2014-01-29
    • 1970-01-01
    • 2018-01-08
    相关资源
    最近更新 更多