Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get string from userInfo Dictionary

I have a userInfo dictionary from a UILocalNotification. Is there an easy way to get the String value when using implicit unwrapping?

if let s = userInfo?["ID"]

Gives me a AnyObject that I have to cast to a string.

if let s = userInfo?["ID"] as String 

Gives me an error about StringLiteralConvertable

Just didn't want to have to declare two variables to get a string - one literal for the unwrap and another var for the casted string.

Edit

Here is my method. This doesn't work either - I get (NSObject, AnyObject) is not convertible to String on the if statement.

  for notification in scheduledNotifications
  {
    // optional chainging 
    let userInfo = notification.userInfo

    if let id = userInfo?[ "ID" ] as? String
    {
      println( "Id found: " + id )
    }
    else
    {
      println( "ID not found" )
    }
  }

I don't have it in my question, but besides getting this way to work, I'd like to actually have

if let s = notification.userInfo?["ID"] as String 
like image 934
Brian Avatar asked Oct 13 '14 01:10

Brian


1 Answers

You want to use a condition cast using as?:

(Note: This works for Xcode 6.1. For Xcode 6.0, see below)

if let s = userInfo?["ID"] as? String {
    // When we get here, we know "ID" is a valid key
    // and that the value is a String.
}

This construct safely extracts a string from userInfo:

  • If userInfo is nil, userInfo?["ID"] returns nil due to optional chaining and the conditional cast returns a variable of type String? that has a value of nil. The optional binding then fails and the block is not entered.

  • If "ID" is not a valid key in the dictionary, userInfo?["ID"] returns nil and it proceeds like the previous case.

  • If the value is another type (like Int), then the conditional cast as? will return nil and it proceeds like the above cases.

  • Finally, if userInfo is not nil, and "ID" is a valid key in the dictionary, and the type of the value is a String, then the conditional cast returns an optional string String? containing the string. The optional binding if let then unwraps the String and assigns it to s which will have type String.


For Xcode 6.0, there is one additional thing you must do. You need to conditionally cast to NSString instead of to String because NSString is an object type and String is not. They apparently improved that handling in Xcode 6.1, but for Xcode 6.0 do the following:

if let s:String = userInfo?["ID"] as? NSString {
    // When we get here, we know "ID" is a valid key
    // and that the value is a String.
}

Finally, addressing your last point:

  for notification in scheduledNotifications
  {
      if let id:String = notification.userInfo?["ID"] as? NSString
      {
          println( "Id found: " + id )
      }
      else
      {
          println( "ID not found" )
      }
  }
like image 152
vacawama Avatar answered Nov 15 '22 08:11

vacawama