【问题标题】:Swift : '(NSObject, AnyObject)' does not have a member named 'subscript'Swift:“(NSObject,AnyObject)”没有名为“下标”的成员
【发布时间】:2014-12-17 22:30:32
【问题描述】:

我正在尝试从远程通知的 userInfo 字典中提取徽章值。 我阅读了很多帖子并找到了解决问题的方法,但我非常不满意!

这是我的数据结构(我删除了无用的行):{ aps = { badge = 7 } }

要从我的userInfo 中提取这个数字“7”,我想执行以下操作:

self.updateAppIcon(userInfo["aps"]["badge"] as? Int)

但我当然会收到以下错误:

Swift : '(NSObject, AnyObject)' 没有名为 'subscript' 的成员

如果我没记错的话,那是因为[] 返回的 AnyObject 不能被解释为另一个字典。

可行的解决方案将是执行以下操作:

func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) {

    if let aps: AnyObject = userInfo["aps"] {
        if let apsDict = aps as? [String : AnyObject]{
           if let badge: AnyObject = apsDict["badge"] {
              self.updateAppIconBadgeNumber(badge as? Int)
           }
        }
    }
}

func updateAppIconBadgeNumber(number: Int?) {
    // do stuff here
}

但是说真的……我可以用更性感的方式来做吗?更少的行、更少的 if 子句、更少的强制转换等?这是一个简单的事情的“代码复杂”解决方案。

谢谢

【问题讨论】:

    标签: ios dictionary swift push-notification nsobject


    【解决方案1】:

    您可以使用 nil coleascing 运算符并使其简短,但您可能会失去可读性。如果有这样的方法的单行版本,

    func handleRemoteNotification(userInfo: [NSObject : AnyObject]) {
      if let badge = ((userInfo["aps"] as? [String: AnyObject]) ?? ([String: AnyObject]()))["badge"] as? Int{
          self.updateAppIconBadgeNumber(badge)
      }
    }
    

    您可以键入别名 [String: AnyObject] 并使其看起来更具可读性。

    typealias Dict = [String: AnyObject]
    func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) {
        if let badge = ((userInfo["aps"] as? Dict) ?? Dict())["badge"] as? Int{
            self.updateAppIconBadgeNumber(badge)
        }
    }
    

    【讨论】:

    • 感谢您的回答,这实际上也很有效,但正如您所说,可读性较差。 @rintaro 给出的答案对我来说似乎更好。但是,可以向我解释或分享有关此“零合并运算符”“??”的链接,我不知道这是关于什么的。
    • nil coalescing operator: ?? 在 Apple 的 iBook 中有详细解释。我似乎无法在 SO 评论中阻止引用它,但这是本书所说内容的直接副本: nil 合并运算符 (a ?? b) 如果它包含一个值,则打开一个可选的 a ,如果它包含一个值,则返回一个默认值 b 如果a 为零。表达式 a 始终是可选类型。表达式 b 必须匹配存储在 a 中的类型。 nil 合并运算符是以下代码的简写:a != nil ? a! : b
    【解决方案2】:

    最短的是:

    // Xcode 6.0.1
    func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) {
        if let badge = [userInfo["aps"]?["badge"]][0] as? Int {
            self.updateAppIconBadgeNumber(badge)
        }
    }
    
    // Xcode 6.1
    func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) {
        if let badge = userInfo["aps"]?["badge"] as? Int {
            self.updateAppIconBadgeNumber(badge)
        }
    }
    

    ["aps"]["badge"] 之间的? 称为"Optional Chaining"。 你需要这个,因为userInfo["aps"] 可以返回nil。 而且您不必将其转换为 [String : AnyObject],因为每个 AnyObject 都有“下标”成员。

    而且,为什么我们在 Xcode 6.0.1 中需要 [ ... ][0] 是...我不知道 :( 一个错误,也许。

    【讨论】:

    • 非常感谢!我对这个“可选链接”一无所知。感谢您的解决方案和链接!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-18
    相关资源
    最近更新 更多