I have
var params = [String:AnyObject]()
I have a function which returns an [String:AnyObject]. So, I want to assign that to a key of params like this:
params["phoneDetails"] = getPhoneDetails()
The problem I am facing is, the return of getPhoneDetails() is different from the value in params["phoneDetails"].
Here is the output of getPhoneDetails()
[locale: en, ostype: 32bit, appversion: 4.0.0, architecture: x86, version: 8.1]
Here is the output of params["phoneDetails"]:
Optional({
appversion = "4.0.0";
architecture = "x86 ";
locale = en;
ostype = 32bit;
version = "8.1";
})
So, instead of a comma, I see a semi-colon, when using println(params["phoneDetails"]).
I want it to be same as the return type of getPhoneDetails. What am I doing wrong?
The reason for this is that Swift is implicitly converting your Swift.Dictionary into an NSDictionary:
let d: [String:AnyObject] = ["one":"1","two":"2"]
// Swift.Dictionary implements Printable.description
// (which println uses) as [key:value, key:value]
d.description
let nsd = d as NSDictionary
// NSDictionary on the other hand, implements
// it as {\n key = value;\n key = value;\n}
nsd.description
The reason for this conversion is your use of AnyObject. In theory, AnyObject can only store reference types (i.e. classes). Try the following in a playground without any import statements at the top i.e. remove import UIKit or whatever:
// this won’t even compile - Strings aren’t classes, they’re structs
// so you can’t assign them to AnyObject
let d: [String:AnyObject] = ["one":"1","two":"2"]
// this fixes that:
let e: [String:String] = ["one":"1","two":"2"]
// but this won’t compile:
let o: AnyObject = e // [String:String] doesn’t conform to protocol AnyObject
But import Foundation and suddenly magic happens. Two bits of magic in fact: string literals can now create NSString objects, which are classes and so do conform to AnyObject. And Swift dictionaries can be silently converted to NSDictionary objects, which also are classes so conform to AnyObject. That latter one is what’s happening to you, and so you get a different output, because your type is indeed of a different type.
If you don’t want them to be of different types, you have two choices – return an NSDictionary from your getPhoneDetails function (ick) or stop using AnyObject and instead declare your dictionary to be of type [String:[String:String]] (yay, but leading to stronger types and value rather than reference semantics, which may mean having to refactor other code).
(or I guess you could switch to [String:Any] but there lies madness)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With