How to access a Dictionary passed via NSNotification, using Swift

user3864657 picture user3864657 · Jul 22, 2014 · Viewed 23.2k times · Source

I have code that sends a notification (where serialNumber is a String):

  var dataDict = Dictionary<String, String>()
  dataDict["Identity"] = serialNumber
  dataDict["Direction"] = "Add"
            NSNotificationCenter.defaultCenter().postNotificationName("deviceActivity", object:self, userInfo:dataDict)

And code that receives this notification:

  func deviceActivity(notification: NSNotification) {

     // This method is invoked when the notification is sent
     // The problem is in how to access the Dictionary and pull out the entries
  }

I've tried a variety of code to accomplish this, with no success:

let dict = notification.userInfo
let dict: Dictionary<String, String> = notification.userInfo
let dict: Dictionary = notification.userInfo as Dictionary

And while some of my attempts satisfy the compiler, none have yielded actual Strings when trying to access what has been extracted as a Dictionary:

let sn : String = dict["Identity"]!
let sn : String = dict.valueForKey("Identity") as String
let sn : String = dict.valueForKey("Identity")

So the question is this: How do I write Swift code to extract an object, in this case a Dictionary, that was passed via a notification, and access the component parts of that object (in this case the keys and values)?

Answer

Vladimir picture Vladimir · Jul 22, 2014

As notification.userInfo type is AnyObject ayou must downcast it to appropriate dictionary type.

After exact type of dictionary is known you don't need to downcast values you get from it. But you may want to check if values are actually present in dictionary before using them:

// First try to cast user info to expected type
if let info = notification.userInfo as? Dictionary<String,String> {
  // Check if value present before using it
  if let s = info["Direction"] {
    print(s)
  }
  else {
    print("no value for key\n")
  }
}
else {
  print("wrong userInfo type")
}