简体   繁体   English

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

[英]iCloud: Sync Core Data between IOS and OSX

I try to sync core data between IOS and OSX. 我尝试在IOS和OSX之间同步核心数据。 At both apps I have the same configuration: 在这两个应用程序中,我具有相同的配置:

在此处输入图片说明

And the same entitlements: 和相同的权利:

在此处输入图片说明

I also use the same code for the store coordinator within the same name for sqlite file and url: 我还为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
    }
});

Each app, the IOS Version and the OSX Version, are still running perfectly within the iCloud. 每个应用程序(IOS版本和OSX版本)仍可以在iCloud中完美运行。 Each app handle its own database, due to there is no sync between this two apps. 每个应用程序都处理自己的数据库,因为这两个应用程序之间没有同步。 Is there somethings what I have forgotton? 我忘了什么吗?

You need to be very careful that the identifiers you use in the entitlements match what you use in the source code to access the ubiquity container. 您需要非常小心,以确保您在权利中使用的标识符与您在源代码中使用的标识符匹配以访问普遍存在的容器。

One complication when syncing multiple apps (eg Mac app and iOS app) is that you will need to check that they each have the same team identifier. 同步多个应用程序(例如Mac应用程序和iOS应用程序)时,一个复杂的事情是您需要检查它们是否具有相同的团队标识。 If not, you will want to fill in the team id explicitly for iCloud entitlements, rather than using the TeamIdentifierPrefix variable. 如果不是,您将要显式填写iCloud权利的团队ID,而不是使用TeamIdentifierPrefix变量。 Pick one of the team ids and use that for both apps. 选择一个团队ID,并将其用于两个应用程序。

In your particular example, it looks like you have entitlements setup for a container id that ends in sample.sample.sample . 在您的特定示例中,您似乎已为以sample.sample.sample结尾的容器ID设置了权利。 Assuming the team id is the same for each app, your container id should be XXXXXXXXXX.sample.sample.sample , where the first part is your team id. 假设每个应用程序的团队ID都相同,那么您的容器ID应该是XXXXXXXXXX.sample.sample.sample ,其中第一部分是您的团队ID。 I don't know what APP_IDENTIFIER is in this instance, but it should be checked to make sure it is sample.sample.sample . 我不知道在这种情况下APP_IDENTIFIER是什么,但是应该检查它以确保它是sample.sample.sample (My guess is that it isn't.) (我的猜测是不是。)

The NSPersistentStoreUbiquitousContentNameKey setting can be basically any label you like for your store. NSPersistentStoreUbiquitousContentNameKey设置基本上可以是您希望为商店使用的任何标签。 It doesn't have to use the ~ or even be reverse-DNS form. 它不必使用〜甚至是反向DNS形式。 For example, you could call it 'Store1'. 例如,您可以将其称为“ Store1”。

I find the easiest way to see if everything is setup OK is to go to the ~/Library/Mobile Documents folder on your Mac, and look for the app container. 我发现查看所有设置是否简单的最简单方法是,转到Mac上的~/Library/Mobile Documents文件夹,然后查找应用程序容器。 You can just browse the contents directly in Finder. 您可以直接在Finder中浏览内容。

Unfortunately, this is probably the easiest part of getting Core Data working with iCloud. 不幸的是,这可能是使Core Data与iCloud一起使用的最简单的部分。 There will be many more hurdles, and they tend to be more challenging. 会有更多的障碍,而且它们往往更具挑战性。 There are new solutions coming up for syncing Core Data all the time, including the TICDS framework and Core Data Ensembles , both of which work with iCloud. 不断有新的解决方案可以同步Core Data,包括TICDS框架和Core Data Ensembles ,它们都可与iCloud一起使用。 (Disclosure: I have contributed to both projects, and founded the Ensembles project.) (公开:我为这两个项目都做出了贡献,并建立了Ensembles项目。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM