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