Al Martin
Al Martin

Reputation: 179

Changes to placemark addressDictionary in xcode 7 Beta 6

I have upgraded to xcode 7 beta 6 as iOS 9 will be on us soon. I was very pleased that my code converted without too much hassle except for one exception.

It seems that the placemark.addressDictionary has been changed to [NSObject: AnyObject]?

This was my code in xCode 6 for a map search

for item in response.mapItems as! [MKMapItem] {
     var placeMarkAddress = item.placemark.addressDictionary
     let street:String = placeMarkAddress["Street"] != nil ? placeMarkAddress["Street"] as! String : ""
}

This no longer works as placeMarkAddress is now [NSObject: AnyObject]?

How do I get the value (AnyObject) out by referencing the NSObject by name?

I've tried this in xcode7

 for item in response!.mapItems {
     var placeMarkAddress = item.placemark.addressDictionary
     for placeMarkAddress in placeMarkAddresses!{
          print(placeMarkAddress)
     }
 }

The output I get is this.

 (FormattedAddressLines, [440 Castro St, San Francisco, CA  94114-2020, United States])
 (Street, 440 Castro St)
 (SubAdministrativeArea, San Francisco)
 (Thoroughfare, Castro St)
 (ZIP, 94114)
 (Name, 440 Castro)
 (City, San Francisco)
 (PostCodeExtension, 2020)
 (Country, United States)
 (State, CA)
 (SubLocality, Castro)
 (SubThoroughfare, 440)
 (CountryCode, US)

This maybe obvious to some of you but I'm still a bit of a newbie to iOS development.

Upvotes: 2

Views: 1774

Answers (1)

vacawama
vacawama

Reputation: 154701

Since placeMarkAddress is [NSObject: AnyObject]?, you must unwrap it before using it. The optional chaining ? is appropriate here; it will unwrap the dictionary if it isn't nil or it will just safely return nil if the dictionary is nil.

Instead of checking explicitly for nil and using the ? : operator to substitute "", there is a special operator to do that called the nil coalescing operator ?? which is used like this:

let street = placeMarkAddress?["Street"] as? String ?? ""

Writing the statement in this way protects you in 4 ways:

  1. If placeMarkAddress is nil, the optional chain placemarkAddress?["Street"] will return nil, the optional cast as? String will turn that nil into a String? with a nil value, and ?? will replace that with empty string "".
  2. If "Street" is not a valid key in the dictionary, placeMarkAddress?["Street"] will return nil and that will be converted to "" as stated in point 1.
  3. If the value in the dictionary corresponding to key "Street" has a type other than String, then the conditional cast will return a String? with a value of nil which ?? will convert to "".
  4. Finally, using the nil coalescing operator ?? safely unwraps the value from the dictionary if it exists and is a String, otherwise it substitutes the supplied default value (empty String "").

Upvotes: 3

Related Questions