Синхронизация существующего хранилища Core Data с iCloud - PullRequest
26 голосов
/ 31 декабря 2011

Я пытаюсь заставить iCloud работать с моим приложением, которое должно перенести существующее локальное хранилище в вездесущее хранилище, если пользователь запрашивает его.

После некоторых разговоров на форумах разработчиков Apple и других местах, я выбрал этот подход, который не работает постоянно.Я действительно видел, как это работает, но только после нескольких сбоев на устройстве B (которое заполняется из iCloud).

- (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;
}

Ответы [ 3 ]

6 голосов
/ 13 октября 2012

iCloud Core Синхронизация данных ужасно нарушена. Более надежным сторонним решением является TICoreDataSync; этот форк поддерживает синхронизацию по iCloud, не полагаясь на реализацию синхронизации основных данных в iCloud. Он просто использует iCloud для синхронизации файлов и самостоятельно выполняет синхронизацию объекта Core Data.

Я отказался от синхронизации основных данных iCloud и вместо этого собирал свое приложение с этой библиотекой; до сих пор он работал отлично, ни с одной из проблем, которые я видел при реализации Apple.

2 голосов
/ 12 февраля 2012

Я отказался от интеграции с iCloud, по крайней мере, на данный момент. Я не чувствую, что могу предложить своим пользователям надежное решение для синхронизации через iCloud, учитывая неустойчивую производительность Core Data. Я надеюсь на iOS 5.1.

1 голос
/ 01 февраля 2012

Вы сделали это?

Попробуйте спросить здесь, если нет - Странные ошибки при использовании CoreData с iCloud

Или дайте нам решение, если да:)

...