Set [String: AnyObject] to [String: AnyObject] in Swift replaces the comma with a semicolon

I have

var params = [String:AnyObject]() 

I have a function that returns [String:AnyObject] . So, I want to assign this to the params key as follows:

 params["phoneDetails"] = getPhoneDetails() 

The problem I encountered is that returning getPhoneDetails() is different from the value in params["phoneDetails"] .

Here is the result of getPhoneDetails ()

 [locale: en, ostype: 32bit, appversion: 4.0.0, architecture: x86, version: 8.1] 

Here is the result 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 half-time when using println(params["phoneDetails"]) .

I want it to be the same as the return type of getPhoneDetails . What am I doing wrong?

+5
source share
1 answer

The reason for this is that Swift implicitly converts your Swift.Dictionary to 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 the use of AnyObject . Theoretically, AnyObject can only store reference types (e.g. classes). Try the following on a playground without any import statements at the top, i.e. remove import UIKit or something else:

 // 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 magic suddenly happens. In fact, two bits of magic: string literals can now create NSString objects, which are classes, and therefore correspond to AnyObject . And Swift dictionaries can be easily converted to NSDictionary objects, which are also classes, so they correspond to AnyObject . This is the last thing that happens to you, and therefore you get a different result, because your type is really a different type.

If you do not want them to be of different types, you have two options - return an NSDictionary from your getPhoneDetails (ick) function or stop using AnyObject and instead declare your dictionary as type [String:[String:String]] (yay, but leads to stronger types and values, rather than referential semantics, which may mean the need to reorganize another code).

(or I think you could switch to [String:Any] , but there is crazy there)

+6
source

Source: https://habr.com/ru/post/1212902/


All Articles