2017-02-21 31 views
0

У меня возникают проблемы с этим и теперь читайте несколько руководств, а также примеры из одной книги, которые, однако, предложили более глубокую копию, которая слишком сложна для меня. Этот материал iCloud в любом случае запутан. Разве я получить это право с этим:Цель C: Переместить локальное хранилище данных ядра в icloud и наоборот

Пользователь позволяет ICloud в приложении: - Попробуйте скопировать локальный магазин ICloud - Удаление локального хранилища

Пользователь отключив ICloud в приложении: - Попробуйте скопировать магазин местный - Удалить вездесущее содержимое - Удалить местную копию icloud

Пропустить что-нибудь?

Дополнительные вопросы: Как я могу «заблокировать» приложение во время копирования и где я должен поместить этот «блокирующий» код?

Это будет мой код:

- (bool)moveStoreToICloud { 
    NSLog(<#NSString * _Nonnull format, ...#>)(@" called"); 
    return [self moveStoreFileToICloud:self.store delete:YES backup:YES]; 
} 

- (bool)moveStoreFileToICloud:(NSURL*)fileURL delete:(bool)shouldDelete backup:(bool)shouldBackup { 
    NSLog(@" called"); 

    // Always make a backup of the local store before migrating to iCloud 
    if (shouldBackup) 
     [self backupLocalStore]; 

    NSPersistentStoreCoordinator *migrationPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model]; 

    // Open the existing local store using the original options 
    NSDictionary *options = 
    @{ 
     NSMigratePersistentStoresAutomaticallyOption:@YES 
     ,NSInferMappingModelAutomaticallyOption:@YES 
     ,NSPersistentStoreUbiquitousContentNameKey:ubiquitousContentNameKey 
     //,NSPersistentStoreUbiquitousContentURLKey:@"ChangeLogs" // Optional since iOS7 
     }; 
    id sourceStore = [migrationPSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:fileURL options:options error:nil]; 

    if (!sourceStore) { 
     NSLog(@" failed to add old store"); 
     return FALSE; 
    } else { 
     NSLog(@" Successfully added store to migrate"); 

     bool moveSuccess = NO; 
     NSError *error; 

     NSLog(@" About to migrate the store..."); 
     // Now migrate the store using the iCloud options 
     id migrationSuccess = [migrationPSC migratePersistentStore:sourceStore toURL:[_iCloudStore URL] options:options withType:NSSQLiteStoreType error:&error]; 

     if (migrationSuccess) { 
      moveSuccess = YES; 
      NSLog(@"store successfully migrated"); 
      // Now delete the local file 
      if (shouldDelete) { 
       NSLog(@" deleting local store"); 
       [self destroyAllLocalDataForThisApplication]; 
      } else { 
       NSLog(@" not deleting local store"); 
      } 

      [self resetCoreData]; 
      [self setupCoreData]; 

      [[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged" 
                   object:nil]; 
      return TRUE; 
     } 
     else { 
      NSLog(@"Failed to migrate store: %@, %@", error, error.userInfo); 
      return FALSE; 
     } 

    } 
    return FALSE; 
} 
/*! Moves an iCloud store to local by migrating the iCloud store to a new local store and then removes the store from iCloud. 

Note that even if it fails to remove the iCloud files it deletes the local copy. User may need to clean up orphaned iCloud files using a Mac! 

@return Returns YES of file was migrated or NO if not. 
*/ 
- (bool)moveStoreToLocal { 
    NSLog(@"moveStoreToLocal called"); 

    // Lets use the existing PSC 
    NSPersistentStoreCoordinator *migrationPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model]; 

    // Open the store 
    NSDictionary *options = 
    @{ 
     NSMigratePersistentStoresAutomaticallyOption:@YES 
     ,NSInferMappingModelAutomaticallyOption:@YES 
     ,NSPersistentStoreUbiquitousContentNameKey:ubiquitousContentNameKey 
     //,NSPersistentStoreUbiquitousContentURLKey:@"ChangeLogs" // Optional since iOS7 
     }; 
    id sourceStore = [migrationPSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[_iCloudStore URL] options:options error:nil]; 

    if (!sourceStore) { 

     NSLog(@" failed to add old store"); 
     return FALSE; 
    } else { 
     NSLog(@" Successfully added store to migrate"); 

     bool moveSuccess = NO; 
     NSError *error; 

     NSLog(@" About to migrate the store..."); 
     id migrationSuccess = [migrationPSC migratePersistentStore:sourceStore toURL:[_store URL] options:options withType:NSSQLiteStoreType error:&error]; 

     if (migrationSuccess) { 
      moveSuccess = YES; 
      NSLog(@"store successfully migrated"); 
      // Now delete the local file 
      [self destroyAlliCloudDataForThisApplication]; 

      [self resetCoreData]; 
      [self setupCoreData]; 

      [[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged" 
                   object:nil]; 
      return TRUE; 
     } 
     else { 
      NSLog(@"Failed to migrate store: %@, %@", error, error.userInfo); 
      return FALSE; 
     } 

    } 

    return TRUE; 
} 


#pragma mark - ICLOUD RESET 
- (void)destroyAllLocalDataForThisApplication { 

    if (![[NSFileManager defaultManager] fileExistsAtPath:[[_store URL] path]]) { 
     NSLog(@"Skipped destroying content, _store.URL is %@",[[_store URL] path]); 
     return; 
    } 

    NSLog(@"\n\n\n\n\n **** Destroying ALL local content for this application, this could take a while... **** \n\n\n\n\n\n"); 

    [self removeAllStoresFromCoordinator:_coordinator]; 
    [self removeAllStoresFromCoordinator:_seedCoordinator]; 
    _coordinator = nil; 
    _seedCoordinator = nil; 

    NSError *error; 
    if([[NSFileManager defaultManager] removeItemAtURL:_storeURL error:&error]){ 
     NSLog(@"Local store successfully removed"); 
    } else { 
     NSLog(@"\n\n **** FAILED to destroy this application's iCloud content at URL (%@) **** \n%@\n",[_store URL],error); 
    } 
} 


- (void)destroyAlliCloudDataForThisApplication { 

    if (![[NSFileManager defaultManager] fileExistsAtPath:[[_iCloudStore URL] path]]) { 
     NSLog(@"Skipped destroying iCloud content, _iCloudStore.URL is %@",[[_iCloudStore URL] path]); 
     return; 
    } 

    NSLog(@"\n\n\n\n\n **** Destroying ALL iCloud content for this application, this could take a while... **** \n\n\n\n\n\n"); 

    [self removeAllStoresFromCoordinator:_coordinator]; 
    [self removeAllStoresFromCoordinator:_seedCoordinator]; 
    _coordinator = nil; 
    _seedCoordinator = nil; 

    NSDictionary *options = 
    @{ 
     NSPersistentStoreUbiquitousContentNameKey:ubiquitousContentNameKey 
     //,NSPersistentStoreUbiquitousContentURLKey:@"ChangeLogs" // Optional since iOS7 
     }; 
    NSError *error; 
    if ([NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:[_iCloudStore URL] 
                      options:options 
                       error:&error]) { 
     NSLog(@"\n\n\n\n\n"); 
     NSLog(@"*  This application's iCloud content has been destroyed  *"); 
     NSLog(@"* On ALL devices, please delete any reference to this application in *"); 
     NSLog(@"* Settings > iCloud > Storage & Backup > Manage Storage > Show All *"); 
     NSLog(@"\n\n\n\n\n"); 
     [[NSFileManager defaultManager] removeItemAtURL:[_iCloudStore URL] error:&error] 
    } else { 
     NSLog(@"\n\n **** FAILED to destroy this application's iCloud content at URL (%@) **** \n%@\n",[_iCloudStore URL],error); 
    } 
} 

ответ

0

Если это новое приложение, пересмотреть свой подход. Используйте CloudKit, или Azure, или Firebase.

iCloud Core Data никогда не работал надежно. К счастью, Apple это понимает. NSPersistentStoreUbiquitousContentNameKey отмечен как устаревший как iOS 10/macOS 12.12, как и другие символы iCloud Core Data.

+0

К сожалению, это не новое приложение:/ – MichiZH

+0

Что меняется? Добавляете ли вы облачную синхронизацию к существующему приложению Core Data? –

+0

Точно. Пока он был только локальным, и теперь я хотел бы добавить опцию для пользователей, чтобы переместить его ti icloud (и обратно, если они захотят). Таким образом, в основном это должно просто переместить coredata из local-> icloud и обратно. – MichiZH