2011-12-31 5 views
26

Próbuję przekonać iCloud do pracy z moją aplikacją, która musi migrować istniejący lokalny magazyn do wszechobecnego sklepu, jeśli użytkownik tego zażąda.Synchronizowanie istniejącego magazynu danych podstawowych za pomocą iCloud

Po pewnym przywiązaniu do forów deweloperskich Apple i gdzie indziej, podjąłem to podejście, które nie działa konsekwentnie. Rzeczywiście widziałem, jak to działa, ale tylko po kilku awariach na Urządzeniu B (które jest zapełniane z 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; 
} 
+0

Wystarczy zauważyć, że aplikacja prawie zawsze ma tylko jeden sklep; Kod postępowania w przypadku 2 sklepów (activeStoreIndex, itp.) jest sprawą skrajną. – ed94133

+1

Gdzie jest zdefiniowane migrateStore i przypisywane? – Jim

Odpowiedz

6

Synchronizacja danych w magistrali iCloud jest straszliwie zepsuta. Bardziej niezawodnym rozwiązaniem firm trzecich jest TICoreDataSync; this fork obsługuje synchronizację w usłudze iCloud, nie polegając na implementacji synchronizacji danych podstawowych w usłudze iCloud. Po prostu używa iCloud do synchronizowania plików i samodzielnie obsługuje synchronizację obiektu Core Data.

Porzuciłem synchronizację danych iCloud Core Data i zamiast tego budowałem swoją aplikację z tą biblioteką; do tej pory działało świetnie, bez żadnych problemów z wdrożeniem Apple.

+0

TICDS nie jest aktywnie rozwijany. Stworzyłem nowe ramy, [Zespoły] (http://ensembles.io), oparte na tych samych zasadach i uwzględniające wnioski wyciągnięte z TICDS. –

2

dałem się na integracji iCloud, przynajmniej na razie. Nie wydaje mi się, abym mógł zaoferować swoim użytkownikom niezawodne rozwiązanie do synchronizacji za pośrednictwem iCloud, biorąc pod uwagę błędną wydajność danych podstawowych. Mam nadzieję na iOS 5.1.

+4

Firma, dla której pracowałem, również chciała integracji z iCloud w istniejącej aplikacji z danymi podstawowymi, chociaż powiedziałem im, że nie działa ona prawidłowo. To było jak piekło !!! Po wydaniu w lutym otrzymaliśmy wiele negatywnych opinii na temat awarii i utraconych danych. W sierpniu firma ogłosiła niewypłacalność: D Chciałem tylko opowiedzieć tę historię ... –