iCloud:在IOS和OSX之间同步核心数据

时间:2014-02-05 01:37:44

标签: ios macos icloud core-data-migration

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

enter image description here

同样的权利:

enter image description here

对于sqlite文件和url,我也对同名的商店协调员使用相同的代码:

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中完美运行。每个应用程序都处理自己的数据库,因为这两个应用程序之间没有同步。我有什么东西可以用吗?

1 个答案:

答案 0 :(得分:3)

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

同步多个应用程序(例如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协同工作的最简单方法。会有更多的障碍,而且往往更具挑战性。有新的解决方案可以同时同步核心数据,包括TICDS框架和Core Data Ensembles,两者都可以与iCloud配合使用。 (披露:我为这两个项目做出了贡献,并创立了Ensembles项目。)