Any And AnyObject Explained In Swift

Written by Reinder de Vries on March 20 2019 in App Development

Any And AnyObject Explained In Swift

How do you use Any in Swift? What’s the difference between Any and AnyObject? And when and why should you use them? We’ll answer those questions in this tutorial.

Here’s what we’ll get into:

  • What Any is and why it’s quite useful
  • The difference between AnyObject and Any
  • Where AnyObject actually comes from

Ready? Let’s go.

  1. What’s “Any” In Swift?
  2. Why Use Any And AnyObject?
  3. The Difference Between Any And AnyObject
  4. Further Reading

What’s “Any” In Swift?

The Swift Programming Language provides two nonspecific types called Any and AnyObject. They’re nonspecific, because they really can be anything

Let’s make a quick comparison. Consider that a constant called age has value 42 and is of type Int, like this:

let age:Int = 42

This type Int is specific – we’re very clear here about the fact that age is an integer number.

Now let’s check out a nonspecific type that uses Any. The following code defines a values array of type [Any]:

let values:[Any] = ["Apple", 99, "Zaphod", -1]

What’s going on here? It doesn’t make sense at first glance – how can the values array contain multiple different types, such as Int and String? That’s because the type of the values array is nonspecific, it is [Any] or array-of-Any.

Making matters more mind-boggling, the individual items in values still use their own specific types. Here, check this out:

let values:[Any] = ["Apple", 99, "Zaphod", -1]

for value in values
{
switch value {
case is String:
print("\(value) is a string!")
case is Int:
print("\(value) is an integer!")
default:
print("I don't know this value!")
}
}

In the above code, we’re using a for loop to iterate over the items in the values array. For every item we’re executing a switch block. This switch block matches the type of value with one of three cases, using the type checking is keyword. In essence, we’re checking the type of each of the items in array, and writing some text based on this type.

But why aren’t the types Any? After all, the type of the values array is [Any], so its items must have type Any. Right? Well… yes and no. Here’s how:

  • The type of the array values is [Any] – it’s nonspecific
  • The types of the individual array items are specific, they’re still their own types, such as Int and String

Why would you use Any with this approach? Let’s find out…

If you’re unfamiliar with type casting, now’s a good time to read up on that. Type casting, Any and AnyObject are closely related, because you’ll almost always want to type cast a variable or constant with type Any or AnyObject to a specific value type (such as in the above example).

Become a professional  iOS developer

Get started with iOS 12 and Swift 5

Sign up for our iOS development course Zero to App Store to learn iOS development with Swift 5, and start with your professional iOS career.

Why Use Any And AnyObject?

The previous example begs the question: why would you want to use Any in the first place? (We’ll get to AnyObject later.)

Before we answer that question, consider that Swift has a few programming features that make dealing with types more flexible. For example:

  • Optionals let you deal effectively with values that are “empty” or not
  • Generics help you to create variables, functions, placeholders etc. that can deal with flexible types
  • Protocols help you to flexibly define constraints for particular types, regardless of what type adopts them

Consider that programming is often nothing more than taking some input, processing it, and providing that as output. You’re writing code that downloads tweets from an API, manipulates that data, and shows it to a user in a UI.

It then makes sense for the Swift programming language to provide tools and features that make dealing with data easier. Optionals, generics, protocols, type casting, Any and AnyObject – all of those “tools” help you process data more effectively. And they (usually) make your code clearer, more expressive, and easier to extend and maintain.

Any and AnyObject are particularly useful for values that have mixed, nonspecific types. Consider, for example the following dictionary:

let tweet:[String: Any] = [
    "text": "Lorem ipsum dolor amet hoodie bicycle rights, 8-bit mixtape",
    "likes": 42,
    "retweets": ["@reinder42", "@aplusk", "@beeblebrox"]
]

See how this dictionary mixes values of different types? The first value is a string, the second an integer, and the third an array of strings.

What if you want to get to specific values in the tweet dictionary? Here’s how you do that:

if let likes = tweet["likes"] {
    print("This tweet has \(likes) likes!")
}

In the above code, the constant likes has type Int. The code uses optional binding to get the value by its key. If needed, you can also make the type cast explicit, like this:

if let likes = tweet["like"] as? Int { ...

Thanks to Any we can combine these different tweet values in one dictionary. We don’t need a custom class or type for the tweet, or use multiple values and dictionaries. And that’s super useful!

The Difference Between Any And AnyObject

So far we’ve only looked at Any. How is Any different from its close cousin, AnyObject?

Here’s what the official Swift documentation says:

  • Any can represent an instance of any type at all, including function types
  • AnyObject can represent an instance of any class type

Simple enough, right? You use Any for anything and AnyObject for classes. But… there’s more!

First, it’s important to understand the difference between value types and reference types. In short, a value type is copied when you pass it around in your code, and a reference type is not. Classes are reference types, and passing those around in your code merely creates a reference to the original object.

This has a clear consequence:

  • When you change a passed value type, the original value does not change
  • When you change a passed reference type, the original value does change

Second, it’s crucial to understand the role of Objective-C, Swift’s predecessor, in Any vs. AnyObject. In Objective-C you can use the polymorphic, untyped id pointer to refer to any kind of object. Much like Any and AnyObject in Swift.

In Objective-C, all objects are reference types. They’re accessed via pointers, and Objective-C doesn’t have the concept of a value type. This is an important point!

One of the great features of Swift is its interoperability with Objective-C. You can use Objective-C code in Swift projects and vice-versa. And you can use SDKs written in Objective-C in your Swift projects. Neat!

This interoperability relies on bridging Swift types and Objective-C types, among other things. The Objective-C type NSString, for example, is bridged to the Swift type String. As a result, you can (almost) seamlessly work with strings between the two languages.

In Swift 2 and earlier, importing to Swift from Objective-C had a problem. Before Swift 3, Objective-C’s id type was imported as AnyObject. Any value of type id that’s passed from Objective-C to Swift had the AnyObject type in Swift.

Remember that AnyObject can only works with classes? This implies that AnyObject is a reference type. Objective-C doesn’t have value types, and id is a reference type, because it uses pointers. And that has a huge disadvantage: you can’t benefit from Swift’s value types when interoperating with Objective-C’s id.

Simply said, importing Objective-C’s id into Swift as AnyObject means you can’t benefit from value types in Swift. And that’s where Any comes in.

Since Swift 3, Objective-C’s id is now imported as Any in Swift. This change is more complex than what’s described here – because it affected bridged and unbridged value types, generics, and collections with AnyHashable.

But where does that leave the difference between Any and AnyObject? You hopefully felt this coming! Here we go:

  • Any is used for both value and reference types, such as structs, Int, String, etc. and can also be used for classes, functions and closures
  • AnyObject is used for reference types, i.e. classes

When should you choose one or the other? It’s a good practice to use AnyObject when working with classes, and Any when working with value types.

As we’ve seen in the previous examples, an array with integers and strings should use Any because they’re value types. You can use Any with classes, but it’s better to use AnyObject.

In any case, don’t use Any when you don’t want to provide a value’s type. It’s important to only use Any and AnyObject when you explicitly need the behavior and functionality they provide. Otherwise you’re just creating needless ambiguity in your code!

Note: Some blogs, articles and forums still mention Objective-C’s id as being imported as AnyObject in Swift. This is outdated information.

† With the exception of NSString, NSNumber, etc. because they define object equality as something different than pointer equality.

Become a professional  iOS developer

Get started with iOS 12 and Swift 5

Sign up for our iOS development course Zero to App Store to learn iOS development with Swift 5, and start with your professional iOS career.

Further Reading

Swift’s Any type proves useful when you want to work with nonspecific types, for example in arrays and dictionaries.

In this article, we’ve discussed the difference between Any and AnyObject and why that’s relevant for iOS developers today. And we’ve seen how type casting can be used to effectively work with Any.

Want to learn more? Check out these resources:

Reinder de Vries

Reinder de Vries

Reinder de Vries is a professional iOS developer. He teaches app developers how to build their own apps at LearnAppMaking.com. Since 2009 he has developed a few dozen apps for iOS, worked for global brands and lead development at several startups. When he’s not coding, he enjoys strong espresso and traveling.