Type '[String, AnyObject?]' does not conform to protocol AnyObject?: why?

Kamchatka picture Kamchatka · Sep 23, 2014 · Viewed 22.2k times · Source

I'm trying to understand why I have a compilation error: Type '[String, AnyObject?]' does not conform to protocol AnyObject?

var cars: [String: AnyObject?] = [ "model": "Ferrari"]
var JSON: [String: AnyObject?] = [ "cars": cars ]  // <-- error

It seems like cars is not an AnyObject? which I don't understand.

Thanks for your help!

Answer

Jeffery Thomas picture Jeffery Thomas · Sep 23, 2014

AnyObject must be a class, but Dictionary is a structure.

The Swift Programming Language: Type Casting

AnyObject can represent an instance of any class type.

The Swift Programming Language: Classes and Structures

Swift’s String, Array, and Dictionary types are implemented as structures.


You can use Any? for this purpose.

var cars: [String: Any?] = [ "model": "Ferrari"]
var JSON: [String: Any?] = [ "cars": cars ]

After looking at this a bit more, there is a subtle problem which causes this to break.

Here is a sample which works:

var cars: [String: AnyObject] = [ "model": "Ferrari"]
var JSON: [String: AnyObject] = [ "cars": cars ]

It works because cars is coerced (implicitly cast) from [String: AnyObject] to an object compatible with NSDictionary ([AnyHashable: AnyObject]). This NSDictionary compatible object is then cast to AnyObject. So, magic.

[String: AnyObject?] cannot be cast in this way because it not NSDictionary compatible, so the coercion fails.