将现有的Core Data存储与iCloud同步。

26

我正在尝试让我的应用程序与iCloud配合使用,如果用户请求,该应用程序需要将现有的本地存储迁移到普适存储。

在Apple开发者论坛和其他地方调查后,我采取了这种方法,但它并不总是有效。实际上,我曾经看到它起作用过,但是只有在装有iCloud的设备B上出现了数次崩溃之后。

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

  NSURL *legacyStoreUrl = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:[self activeStoreFilenameUpgraded:NO]]];
  NSURL *upgradedStoreUrl = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:[self activeStoreFilenameUpgraded:YES]]];

persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

  if ((IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5.0")) && (self.iCloudEnabled)) {
    NSPersistentStoreCoordinator* psc = persistentStoreCoordinator;

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSDictionary *cloudOptions = nil;
    NSDictionary *localOptions = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                                    nil];


    NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:@"<CONTAINER ID>"];
    NSString *coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:[NSString stringWithFormat:@"logs%d",[self activeStoreIndex]]];
    if ([coreDataCloudContent length] != 0) {
        // iCloud is available
        cloudURL = [NSURL fileURLWithPath:coreDataCloudContent];

        cloudOptions = [NSDictionary dictionaryWithObjectsAndKeys:
                       [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                       [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                       @"MyAppStore", NSPersistentStoreUbiquitousContentNameKey,
                       cloudURL, NSPersistentStoreUbiquitousContentURLKey,
                       nil];
    } else {
        // iCloud is not available
    }

    NSError *error = nil;
    [psc lock];
    if(migrateStore) {
        migrateStore = NO;

        NSPersistentStore *srcPS = [psc addPersistentStoreWithType:NSSQLiteStoreType
            configuration:nil
            URL:legacyStoreUrl
            options:localOptions
            error:&error];
        if (![psc migratePersistentStore:srcPS
            toURL:upgradedStoreUrl
            options:cloudOptions
            withType:NSSQLiteStoreType
            error:&error]) {
            NSLog(@"Error migrating data: %@, %@ / %@ / %@", error, [error userInfo], legacyStoreUrl, upgradedStoreUrl);
            abort();
        }
    }
    else {
        if (![psc addPersistentStoreWithType:NSSQLiteStoreType
            configuration:nil
            URL:upgradedStoreUrl
            options:(cloudOptions ? cloudOptions : localOptions)
            error:&error]) {
              NSLog(@"Unresolved iCloud error %@, %@", error, [error userInfo]);
              abort();
        }
    }
    [psc unlock];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"RefetchAllDatabaseData" object:self userInfo:nil];
  } else {
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                             nil];

    NSError *error = nil;
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:legacyStoreUrl options:options error:&error]) {
        // error
        abort();
    }    
  }

  return persistentStoreCoordinator;
}

请注意,该应用程序几乎总是只有一个商店;处理两个商店的情况的代码(activeStoreIndex等)是一种边缘情况。 - ed94133
1
迁移存储定义在哪里并被分配到了哪里? - Jim
3个回答

6
iCloud的Core Data同步功能非常糟糕。一种更可靠的第三方解决方案是TICoreDataSync; this fork支持通过iCloud进行同步,而不依赖于iCloud的Core Data同步实现。它仅使用iCloud同步文件,并自行处理Core Data对象同步。
我放弃了iCloud的Core Data同步,并改用这个库来开发我的应用程序。到目前为止,它一直运行良好,没有我在苹果实现中遇到的任何问题。

TICDS目前没有在积极开发。我基于相同的原则开发了一个新的框架Ensembles,并考虑到了使用TICDS时所学到的经验教训。 - Drew McCormack

2

目前我放弃了iCloud集成。由于Core Data性能不稳定,我不认为我能通过iCloud为我的用户提供可靠的同步解决方案。我希望iOS 5.1能够有所改善。


4
我曾工作的公司希望将iCloud集成到现有的核心数据应用程序中,尽管我告诉他们它无法正常工作。这真是太糟糕了!!! 在2月份发布后,我们收到了很多关于崩溃和丢失数据的负面反馈。该公司于8月份破产:D只是想讲述这个故事... - benjamin.ludwig

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接