目标C:将本地核心数据存储转移到iCloud,反之亦然



我对此有问题,现在阅读了一本书中的几个教程和示例,但是,这对我来说太复杂了,这更深入了。无论如何,这个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(@"nnnnn **** Destroying ALL local content for this application, this could take a while...  **** nnnnnn");
    [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(@"nn **** 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(@"nnnnn **** Destroying ALL iCloud content for this application, this could take a while...  **** nnnnnn");
    [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(@"nnnnn");
        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(@"nnnnn");
        [[NSFileManager defaultManager] removeItemAtURL:[_iCloudStore URL] error:&error]
    } else {
        NSLog(@"nn **** FAILED to destroy this application's iCloud content at URL (%@) **** n%@n",[_iCloudStore URL],error);
    }
}

如果这是一个新应用,请重新考虑您的方法。使用CloudKit或Azure或Firebase。

iCloud核心数据从未可靠地起作用。值得庆幸的是,苹果现在意识到了这一点。NSPersistentStoreUbiquitousContentNameKey被标记为iOS 10/macOS 12.12,以及其他iCloud核心数据符号。

最新更新