4

CloudKit用来存储公开可用的数据,并将新数据NSPersistentCloudKitContainer作为我的核心数据堆栈的一部分来存储/同步私有数据。

当用户打开我的应用程序时,他们处于 4 种状态中的 1 种状态:

  1. 他们是可以访问 iCloud 的新用户
  2. 他们是可以访问 iCloud 的老用户
  3. 他们是新用户,但由于某种原因无法访问 iCloud
  4. 他们是老用户,但由于某种原因无法访问 iCloud

状态 1 和 2 代表我的快乐之路。如果他们是新用户,我想在显示初始视图之前用一些数据播种用户的私人商店。如果他们是返回用户,我想从 Core Data 获取数据以传递给初始视图。

确定新老用户: 我的计划是使用NSUbiquitousKeyValueStore. 我对此的担忧是处理以下情况: 下载应用程序->被记录为之前启动过应用程序->删除并在新设备上重新安装/安装应用程序 我认为NSUbiquitousKeyValueStore需要一些时间来接收更新,所以我需要等到它完成同步后再移动到初始视图。那么问题来了,如果他们无法访问 iCloud,会发生什么?NSUbiquitousKeyValueStore如果无法接收更新,如何告诉我他们是否是回访用户?

确定 iCloud 访问权限: 根据我所做的研究,我可以检查iCloudFileManager.default.ubiquityIdentityToken是否nil可用,但这不会告诉我原因。我将不得不使用CKContainer.default().accountStatus来了解为什么 iCloud 不可用。问题是这是一个异步调用,我的应用程序会在了解他们的帐户状态之前继续前进。

我真的在这个问题上摸不着头脑。优雅地确保处理所有这些状态的最佳方法是什么?

4

2 回答 2

2

这里没有“正确”的答案,但我认为 NSUbiquitiousKeyValueStore 不会以任何方式获胜 - 就像你说的那样,如果他们没有登录 iCloud 或没有网络访问权限,它无论如何都不会为他们工作。我目前使用 NSUbiquitiousKeyValueStore 完成了一些与共享相关的工作,下次不会这样做。我真的希望 NSPersistentCloudKitContainer 支持在 iOS 14 中共享,我可以一举清除大部分 CloudKit 代码。

如果您的应用在没有云访问的情况下无法正常运行,那么您可能只需要在屏幕上显示这一点,尽管总的来说这并不是一个非常令人满意的用户体验。我这样做的方式是将 iCloud 同步视为真正的异步(确实如此)。所以我允许用户开始使用该应用程序。然后您可以调用 accountStatus 以查看它是否在后台可用。如果是,则开始同步,如果不是,则等到它是,然后开始该过程。

因此,用户可以在设备上无限期地独立使用该应用程序,并且当他们连接到互联网时,他们在任何其他设备上所做的一切都会合并到他们在这个新设备上所做的事情中。

于 2020-04-28T16:37:58.813 回答
1

我最近也在努力解决这个问题。我想出的解决方案是直接用CloudKit查询iCloud,看看是否已经初始化。其实很简单:

public func checkRemoteData(completion: @escaping (Bool) -> ()) {
    let db = CKContainer.default().privateCloudDatabase
    let predicate = NSPredicate(format: "CD_entityName = 'Root'")
    let query = CKQuery(recordType: .init("CD_Container"), predicate: predicate)
    db.perform(query, inZoneWith: nil) { result, error in
        if error == nil {
            if let records = result, !records.isEmpty {
                completion(true)
            } else {
                completion(false)
            }
        } else {
            print(error as Any)
            completion(false)
        }
    }
}

此代码说明了一个更复杂的情况,其中您拥有Container具有派生模型的实体实例,在本例中称为Root. 我有类似的东西,并且可以使用根的存在作为数据已设置的证据。

有关如何将核心数据信息带到 iCloud 的第一手文档,请参见此处:https ://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/reading_cloudkit_records_for_core_data

于 2020-05-27T13:19:03.600 回答