斯威夫特:'(NSObject, AnyObject)'没有名为'subscript'的成员



我正试图从远程通知的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子句、少类型转换等等?这是一个"代码复杂"的简单解决方案。

感谢

最短的是:

// 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"]之间的?称为"可选链接"。您需要这个,因为userInfo["aps"]可以返回nil。您不必将其强制转换为[String : AnyObject],因为每个AnyObject都有"subscript"成员。

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

您可以使用nil-colascing运算符并使其变短,但可能会降低可读性。如果有这样的单行版本的方法,

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

您可以键入alias[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)
    }
}

最新更新