'(NSObject, AnyObject)' is not convertible to 'String'
Solution 1
A String
is not an object, so you do need to cast it to an NSString
. I would recommend the following syntax to cast it and unwrap it at the same time. Don't worry about comparing it to a variable of type String!
since they are compatible. This will work:
func formatPlacemark(placemark: CLPlacemark) -> (String, String) {
if let street = placemark.addressDictionary["Street"] as? NSString {
if placemark.name == street {
// Do something
}
}
}
This has the added benefits that if "Street" is not a valid key in your dictionary or if the object type is something other than NSString
, this will not crash. It just won't enter the block.
If you really want street to be a String
you could do this:
if let street:String = placemark.addressDictionary["Street"] as? NSString
but it doesn't buy you anything in this case.
Solution 2
The return type from looking up via subscript for a swift dictionary has to be an optional since there may be no value for the given key.
Therefor you must do:
as String?
Solution 3
I think it may have to do with addressDictionary
being an NSDictionary
.
If you convert addressDictionary
to a Swift dictionary, it should work.
let street = (placemark.addressDictionary as Dictionary<String, String>)["String"]
ma11hew28
Updated on August 17, 2022Comments
-
ma11hew28 over 1 year
How do I convert an object of type
(NSObject, AnyObject)
to the typeString
?At the end of the first line of the method below,
as String
causes the compiler error:'(NSObject, AnyObject)' is not convertible to 'String'
Casting
street
toNSString
instead ofString
compiles, but I'm castingstreet
toString
because I want to compare it toplacemark.name
, which has the typeString!
, notNSString
.I know
name
andstreet
are optionals, but I'm assuming they're notnil
for now because all the places returned fromMKLocalSearch
seem to have non-nil names and streets.func formatPlacemark(placemark: CLPlacemark) -> (String, String) { let street = placemark.addressDictionary["Street"] as String if placemark.name == street { // Do something } }
-
ma11hew28 over 9 yearsHow do you know I can do
placemark.name == street
instead ofstreet.isEqualToString(placemark.name)
? I want to make sure I'm checking for string equality (isEqualToString
), not object identity (==
). -
ma11hew28 over 9 yearsBut, is this slower than @vacawama's solution? Because isn't
Dictionary
completely different thanNSDictionary
? So, would that mean by casting theNSDictionary
toDictionary
, the program will have to create a completely newDictionary
object and fill it with the keys & values of the originalNSDictionary
? That sounds like more work than just a simple cast. -
vacawama over 9 yearsSwift automatically bridges between the two types, and
==
is the Swift way of testing string equality. See: developer.apple.com/library/prerelease/mac/documentation/Swift/… -
vacawama over 9 yearsTry this in a Playground:var a:NSString = "abcdefg" var b:String = "abc" + "defg" if a == b { println("yep they're the same") }
-
vacawama over 9 yearsThis isn't safe. If any value in the dictionary is an object other than an
NSString
, this will crash the app. You'd only do this if you were 100% sure all of the objects wereNSString
s, and then you'd do it only once, when the data is first created. If you are calling an API external to your app to get theNSDictionary
, it would be safer to check each object with the optional form of the type cast operator (as?
).