When I encountered these two type aliases while parsing JSON data for the first time, I had no idea how to distinguish or implement them properly. So, what are they? Any and AnyObject are two special types in Swift that are used for working with non-specific types.

According to Apple’s Swift documentation,

Any can represent an instance of any type at all, including function types and optional types.

can represent an instance of any type at all, including function types and optional types. AnyObject can represent an instance of any class type.

Okay, simple enough — Any is used for all types, AnyObject is used for Class types, right?

To understand how they really behave in code, I decided to play with them in a Playground.

Any Example

Any allowed me to work with a mix of different types including function and non-class types such as Int, String, and Bool. According to the documentation, the elements in this array are Structs that are value types, so in theory AnyObject shouldn’t work in these cases.

To verify this I attempted to include Strings and Ints, which are value types in Swift, using AnyObject.

AnyObjectArray Error When Including Struct Types

As expected, the compiler threw me an error saying that the elements did not conform to the type AnyObject in the array. Gotcha!

Then, this strange thing happened when I tried to follow the compiler’s suggestions:

Elements Casted to AnyObject

What just happened?! How was I able to use AnyObject on Ints and Strings by explicitly casting each element to AnyObject?

I then printed the anyObjectArray into console.

Printing anyObjectArray

The element Hi obviously looked like a string to me, but it did not have quotes around like a normal String value in Swift!

Next I printed each element using a for-in loop to check its actual type rather than its casted-type of AnyObject.

First, I used is operator to see whether the elements are Swift Struct types or not.

Checking Types of Elements in anyObjectArray 1

It is of type String! Then how could it be casted to AnyObject? Again, Strings in Swift are Structs, not Class types. Thus in theory, I shouldn’t be able to cast them as AnyObject.

Wha….t?

I was utterly confused, and decided to do some more experiments with it. This time I used NSNumber and NSString, which are Objective-C types, to check the type of each element.

Checking Types of Elements in anyObjectArray 2

Wait, Hi is also a NSString and numeric elements are NSNumber! And… they are reference types in Objective-C! Was this the reason why Hi didn’t have quotes on it in console? I wrote some more code as below to see if my assumption was correct. 🔎

Printing NSString Array and String Array

Hi with No Quotes On in Console as NSString

Confirmed! The elements that are casted to AnyObject in the array are now class types of Objective-C: NSString and NSNumber.

So… What’s really going on under the hood? I continued digging into this topic and found the most plausible answer from the document Using Swift with Cocoa and Objective-C (Swift 3.0.1) .