【问题标题】:Objective C: Move local core data store to icloud and vice versa目标 C:将本地核心数据存储移动到 icloud,反之亦然
【发布时间】:2017-07-11 12:25:49
【问题描述】:

我在这方面遇到了问题,现在阅读了几本教程和一本书中的示例,但是这建议了更多的深层副本,这对我来说太复杂了。无论如何,这个 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);
    }
}

【问题讨论】:

    标签: ios objective-c core-data icloud


    【解决方案1】:

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

    iCloud Core Data 从来没有可靠地工作过。值得庆幸的是,Apple 现在意识到了这一点。从 iOS 10/macOS 12.12 开始,NSPersistentStoreUbiquitousContentNameKey 被标记为已弃用,其他 iCloud Core Data 符号也是如此。

    【讨论】:

    • 不幸的是它不是一个新应用:/
    • 发生了什么变化?您是否正在向现有的 Core Data 应用程序添加云同步?
    • 没错。到目前为止,它只是本地的,现在我想为用户添加将它移动到 icloud 的选项(如果他们愿意,也可以返回)。所以基本上它应该只是将 coredata 从 local->icloud 移动回来
    • 许多伟大的程序员都曾在 iCloud Core Data 的岩石上撞得粉碎。它严重地从未正确和稳健地工作。现在已弃用。选择一个不同的后端,每秒我的答案。
    • 但我不明白...... iCloud 真的被弃用了吗?!没人用了吗?
    猜你喜欢
    • 2012-09-27
    • 2014-10-07
    • 1970-01-01
    • 2017-07-08
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多