【问题标题】:iCloud + Core Data: First import and user's feeling of loss of dataiCloud + Core Data:首次导入和用户丢失数据的感受
【发布时间】:2015-01-05 02:04:03
【问题描述】:

我已经实现了一个拥有大约 50k 用户的 iPhone 应用程序。从 iOS7 切换到 iOS8 的许多用户在认为他们的数据丢失时都经历了一种可怕的感觉。

我已经实现了我认为是 Apple 建议的第一个导入行为

1) 用户启动应用

2) iCloud,自动,开始同步之前存储在 iCloud 上的数据

3) 由于NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted,用户在某个时候会收到来自 iCloud 的数据准备就绪的通知

问题在于 3) 在某些时候
必须同步大量数据的用户需要几分钟才能完成同步,同时他们认为他们的数据丢失了。

我真的不知道如何让我的用户知道他们必须等待才能看到他们的数据同步,因为我不知道这个操作什么时候开始


我正在考虑一个可能的解决方案:

在应用程序首次启动期间,询问用户是否要使用 iCloud。如果他选择使用它,使用 iCloud 选项构建数据库,所以我确切地知道同步从这里开始(我想......) 我真的不确定如何实现这种行为,因为我一直在 AppDelegate 中看到 Core Data 设置,但为了实现这种行为,我想我需要将所有 CoreData 设置移动到 Controller 中。

您如何看待这个解决方案?你是如何在你的应用程序中解决这个问题的?

【问题讨论】:

    标签: ios core-data architecture synchronization icloud


    【解决方案1】:

    你的想法是对的,至少我们是这样做的。但将其留在 appDelegate 中。

    在执行“addPersistentStoreWithType”时区分使用 iCloud 和不使用 iCloud。如果您使用 iCloud 选项执行此操作,它将直接开始构建本地存储,这是一种占位符(我相信您知道这一点,但只是为了让我的想法清晰)。完成后,同步将从 iCloud 开始。所以这就是我理解你正在寻找的起点。

    您可以使用 NSPersistentStoreCoordinatorStoresDidChangeNotification 的通知来观察该过程,并通知您由该通知触发的用户。

    如果您查看文档https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/UsingSQLiteStoragewithiCloud/UsingSQLiteStoragewithiCloud.html#//apple_ref/doc/uid/TP40013491-CH3-SW5 中的“对 iCloud 事件的反应”,则会有详细说明。

    【讨论】:

    • 要观看的正确事件是 NSPersistentStoreCoordinatorStoresDidChangeNotification 谢谢!
    • 我不接受你的回答,因为当数据已经从 iCloud 下载时调用了“willChange”事件:(
    【解决方案2】:

    总而言之,您所描述的事件是帐户转换过程的一部分。触发以下四个事件之一时会发生帐户转换:

    • 初始导入
    • 使用的 iCloud 帐户确实发生了变化
    • iCloud 已禁用
    • 您的应用程序数据已删除

    在此活动期间,Core Data 将发布NSPersistentStoreCoordinatorStoresWillChangeNotificationNSPersistentStoreCoordinatorStoresDidChangeNotification 通知,让您知道正在进行帐户转换。我们感兴趣的转换类型是NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted

    关于信息,为了简单起见,我已将所有与 Core Data 相关的代码移至我自己的管理器中,并将其与单例设计模式一起使用。在设置单例时,我为所有相关通知注册了管理器(NSPersistentStoreDidImportUbiquitousContentChangesNotificationNSPersistentStoreCoordinatorStoresWillChangeNotificationNSPersistentStoreCoordinatorStoresDidChangeNotificationNSPersistentStoreCoordinatorWillRemoveStoreNotification)。 我在我的设置(NSUserDefaults 或其他任何内容)中存储了一些信息,例如最后一个 iCloud 状态(启用、禁用、未知)、初始导入是否完成等。

    我最终做的是提示(UIAlertController 或其他任何内容)以确认用户是否要使用 iCloud。我有一个 displayICloudDialogAndForce:completion: 方法来执行此操作,并且仅在我的 iCloud 状态设置未知或我使用 force 参数时才执行此操作。

    然后,在用户输入之后,我调用一个setupCoreDataWithICloud: 方法,iCloud 布尔参数取决于用户的选择。然后,我将根据 iCloud 参数在云端或不在云端设置我的核心数据堆栈。 如果我使用 iCloud 进行设置,我会检查我的设置以获取 iCloud 导入密钥(布尔值)的值。如果值为 NO,那么我将展示一个新模式来警告用户传入的导入可能需要一些时间。

    我已经为我的经理注册了不同的通知,特别是NSPersistentStoreCoordinatorStoresDidChangeNotification。在我的storeDidChange: 回调中,我正在检查转换类型,如果它是NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted,我正在更改我的模态内容以向用户显示导入成功并在几秒钟后将其删除,保存在我的初始导入完成的设置。

    - (void)storeDidChange:(NSNotification *)notification 
    {
        NSPersistentStoreUbiquitousTransitionType transitionType = [notification.userInfo[NSPersistentStoreUbiquitousTransitionTypeKey] integerValue];
    
        if (transitionType == NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted) {
            [settings setDefaults:@(YES) forKey:kSettingsICloudImportedKey];
            [ICloudModal dismissWithSuccess];
    
            // ...
        }
    
        // Do other relevant things...
    }
    

    【讨论】:

    • 当 NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted 没有被调用时,你在第一次启动时会做什么?您在第一次启动时展示模态......但如果用户没有将数据存储在 iCloud 上,则永远不会调用 initialImportComplete 通知,因此永远不会关闭模态
    • @MatterGoal 一种可能的处理方法是观察无处不在的容器。最初做一个查询。如果存在 iCloud 文档(有一个 /coredata 文件夹),则用户将核心数据存储保存到他们的 iCloud。如果没有 /coredata 文件夹,则不会进行同步。只是一个理论。
    猜你喜欢
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    相关资源
    最近更新 更多