【问题标题】:iCloud: Sync Core Data between IOS and OSXiCloud:在 IOS 和 OSX 之间同步核心数据
【发布时间】:2014-03-01 06:48:10
【问题描述】:

我尝试在 IOS 和 OSX 之间同步核心数据。在这两个应用程序中,我的配置相同:

同样的权利:

我还为 sqlite 文件和 url 使用相同名称的 store coordinator 的相同代码:

NSManagedObjectModel* managedModel = [NSManagedObjectModel mergedModelFromBundles:nil];
NSPersistentStoreCoordinator* storeCooordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedModel];

//-> start iCloud
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{


        NSURL* applicationFilesDirectory = [JHDCoreDataDAO applicationFilesDirectory];
        NSURL* storeURL = [applicationFilesDirectory URLByAppendingPathComponent:DATABASE_NAME];

        if(!storeURL) { NSLog(@"Error reading applicationFilesDirectory for given sqlite resouce"); }

        NSString* containerIdentifier = [NSString stringWithFormat:@"%@.%@",TEAM_IDENTIFIER,APP_IDENTIFIER];
        NSURL* iCloud = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:containerIdentifier];

        NSString *iCloudEnabledAppID = @"TEAMID~com~sample~sample";
        NSError* persistentStoreError;

        if (iCloud) {

            NSLog(@"iCloud is working");
            NSLog(@"iCloudEnabledAppID = %@",iCloudEnabledAppID);
            NSLog(@"iCloud URL: %@",iCloud);

            NSString* cloudPath = [[iCloud path] stringByAppendingPathComponent:@"data"];
            NSURL* transactionsLogUrl = [NSURL fileURLWithPath:cloudPath];

            NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:
                                     iCloudEnabledAppID, NSPersistentStoreUbiquitousContentNameKey,
                                     transactionsLogUrl, NSPersistentStoreUbiquitousContentURLKey,
                                     [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                                 nil];

        [storeCooordinator lock];
        if(![storeCooordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL  options:options error:&persistentStoreError])
        {
            NSLog(@"Fehler: %@, %@", persistentStoreError.localizedDescription, persistentStoreError.userInfo);
            abort();
        }
        [storeCooordinator unlock];

    } else {
    //Handle local psc
    }
});

每个应用程序,IOS 版本和 OSX 版本,仍然在 iCloud 中完美运行。由于这两个应用程序之间没有同步,每个应用程序都处理自己的数据库。有什么我忘记了吗?

【问题讨论】:

  • 你为什么使用 NSPersistentStoreUbiquitousContentNameKey 的 AppID ?大概 iOS 应用 AppID 和 OS X 应用 AppID 不一样,或者这实际上是在真实应用中硬编码的?在任何情况下 NSPersistentStoreUbiquitousContentNameKey 和 iCloud containerID 对于想要同步同一个 Core Data 存储的所有应用程序都必须相同。您在 Xcode 中的通用容器是 sample.sample.sample,在您的代码中是 `com.sample.sample'
  • 我也有类似的问题。当我尝试在我的 os x 应用程序中与 iCloud 同步时,出现此错误:__60-[PFUbiquitySetupAssistant canReadFromUbiquityRootLocation:]_block_invoke690(1489): CoreData: Ubiquity: Attempting to download Peers hit a Serious error for peers to download Error Domain=BRCloudDocsErrorDomain Code =5 "(BRCloudDocsErrorDomain 5: URL 处没有文档)"

标签: ios macos icloud core-data-migration


【解决方案1】:

您需要非常小心,确保您在权利中使用的标识符与您在源代码中使用的标识符相匹配,以访问普遍存在的容器。

同步多个应用程序(例如 Mac 应用程序和 iOS 应用程序)时的一个复杂情况是您需要检查它们是否具有相同的团队标识符。如果没有,您将需要为 iCloud 权利明确填写团队 ID,而不是使用 TeamIdentifierPrefix 变量。选择一个团队 ID 并将其用于两个应用程序。

在您的特定示例中,您似乎为以 sample.sample.sample 结尾的容器 ID 设置了权利。假设每个应用程序的团队 ID 相同,您的容器 ID 应该是 XXXXXXXXXX.sample.sample.sample,其中第一部分是您的团队 ID。我不知道在这种情况下APP_IDENTIFIER 是什么,但应该检查它以确保它是sample.sample.sample。 (我的猜测是不是。)

NSPersistentStoreUbiquitousContentNameKey 设置基本上可以是您喜欢的商店标签。它不必使用 ~ 甚至是反向 DNS 形式。例如,您可以将其命名为“Store1”。

我发现查看所有设置是否正常的最简单方法是转到 Mac 上的 ~/Library/Mobile Documents 文件夹,然后查找应用程序容器。您可以直接在 Finder 中浏览内容。

不幸的是,这可能是让 Core Data 与 iCloud 一起工作的最简单的部分。会有更多的障碍,而且往往更具挑战性。一直有新的解决方案用于同步 Core Data,包括TICDS 框架和Core Data Ensembles,它们都可以与 iCloud 一起使用。 (披露:我为这两个项目做出了贡献,并创立了 Ensembles 项目。)

【讨论】:

  • 感谢您的回答。我浏览到 osx 上的移动文档文件夹,该文件夹已经创建。由于,每次我在 osx 上运行应用程序时,[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:] 都会显示“使用本地存储:1”并且永远不会切换到“使用本地存储:0”。在 ios 上它工作正常,而不是在 osx 上。我的持久存储协调器中有什么东西吗(见上面的代码)?
  • 这里是示例应用程序的链接 - 查看它们是否在您的环境中运行,然后检查代码差异。 ossh.com.au/design-and-technology/software-development/…
猜你喜欢
  • 2015-11-26
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多