【问题标题】:Hard Coding NSUserActivityTypes for Restoring Different Data Models硬编码 NSUserActivityTypes 以恢复不同的数据模型
【发布时间】:2020-05-05 23:24:16
【问题描述】:

从 iOS 13 开始,Apple recommends 使用附加到场景的 NSUserActivity 对象来存储用户状态,因此我一直在尝试 a) 更好地理解 NSUserActivity 的工作原理以及 b) 在我自己的代码中实现它。在阅读 Apple 的文档时,我遇到了这段代码:

        class var activityType: String {
        let activityType = ""

        // Load our activity type from our Info.plist.
        if let activityTypes = Bundle.main.infoDictionary?["NSUserActivityTypes"] {
            if let activityArray = activityTypes as? [String] {
                return activityArray[0]
            }
        }

        return activityType
    }

我了解 什么 这是在做什么(它在 Info.plist 文件中查找名为“NSUserActivityTypes”的条目,如果存在,它会尝试获取关联的 activityTypes 数组,然后读取数组中的第一项),但我不明白的是为什么。特别是,我不明白为什么我们只读取 activityArray 中的第一项。在这种情况下,我们知道第一项(也是唯一一项)是“com.apple.apple-samplecode.StateRestoration.activity”,因为我们必须手动创建该 plist 条目。但我不明白为什么我们要硬编码查看数组的第一项以获得活动类型,因为如果我们知道我们只是要取回字符串“com.apple.apple-samplecode”。 StateRestoration.activity”,为什么不直接把代码写成这样:

class var activityType: String {
       return "com.apple.apple-samplecode.StateRestoration.activity"
    }

我以前从未使用过 NSUserActivity,并且我知道它可以(通常是?)用于状态保存/恢复以外的其他用途,因此您的应用可以支持许多不同类型的用户活动(切换、Siri 集成等)。所以我会假设我们希望我们的代码尽可能的健壮,不要对我们可能收到的 NSUserActivity 对象的种类做任何假设。

也许对 NSUserActivity 有更多经验的人可以帮助解释将 NSUserActivity 传递给我的应用程序的方式,以及为什么我们可以在数组的第一个元素中硬编码,而在其他地方我们想检查是否传入的活动是正确的活动类型(即使我们知道我们支持的活动数组只有一种活动,所以大概我们一开始只会收到一种活动?)。

此外,这并不是 Apple 的示例代码所独有的……this blog 帖子在读取 Info.plist 文件时也采用了类似的方法:

extension Bundle {
    var activityType: String {
        return Bundle.main.infoDictionary?["NSUserActivityTypes"].flatMap { ($0 as? [String])?.first } ?? ""
    }
}

【问题讨论】:

标签: swift ios13 restore nsuseractivity


【解决方案1】:

我认为这两个示例代码只是解释状态如何工作的虚拟方式。 在那里,他们使用单个恢复 ID (com.apple.apple-samplecode.StateRestoration.activity),但您的应用程序可能不止这些,所以正如您所说,示例代码不再有意义。

另请注意,即使使用单个恢复 ID,您也可以使用所有 NSUserActivity 字段(包括 userInfo)来帮助您区分状态。当然,不同的状态共享同一个恢复 ID 会很脏。

【讨论】:

    【解决方案2】:

    在阅读Apple's example 使用 NSUserActivity 恢复用户状态时,我确实有同样的疑问,因为在我过去的项目中,我总是有一个 Constant.swift 来处理所有硬编码字符串(比如 id 或 key),因为示例:

    Constants.swift

    struct Constants {
        static let userActivityTypeA = "com.apple.apple-samplecode.StateRestoration.activityA"
        static let userActivityTypeB = "com.apple.apple-samplecode.StateRestoration.activityB"
    }
    

    我明白这是在做什么(它会在 Info.plist 文件中查找名为“NSUserActivityTypes”的条目,如果存在,它会尝试获取关联的 activityTypes 数组,然后读取数组中的第一项) ,但我不明白为什么。

    在我看来,不必遵循 Apple 的示例(在 info.plist 中添加 activityType 并使用 Bundle.main.infoDictionary 读取它)。 Apple 只是通过在 info.plist 中提供一个固定键“NSUserActivityTypes”来提供一种更简洁且可以轻松识别字符串是什么的方法。

    (想象有一天你的同事拿起你的项目,他可能不知道 Constants.swift 中的反向域字符串是什么或你放置它的任何地方。)

    为什么我们可以在数组的第一个元素中硬编码,而在其他地方我们想检查传入的活动是否是正确的活动类型(即使我们知道我们支持的活动数组只有一种活动,所以大概我们一开始只会收到一种活动?)。

    这实际上取决于您的应用程序支持多少activityType,例如,您将来可能希望添加更多类型,例如类型A转到ViewController A,类型B将在您的应用程序中打开一个应用内浏览器.如果您知道您的应用只支持一种活动,是的,您甚至不需要检查它,但一般来说,我们总是希望确认收到的内容并给出相应的响应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-27
      • 2019-12-20
      • 2021-01-13
      • 1970-01-01
      相关资源
      最近更新 更多