Tuples In Swift Explained

Written by Reinder de Vries on June 5 2019 in App Development

Tuples In Swift Explained

Tuples may look small, but they’re quite powerful! You use tuples in Swift to make ordered, comma-separated lists of values. In this article, we’ll discuss how you can use tuples in practical iOS development.

Let’s get started!

  1. What’s A Tuple?
  2. Decomposing Tuples
  3. Tuples In Everyday Swift Coding
  4. Further Reading

What’s A Tuple?

A tuple (pronounced “TEWple”) is an ordered, comma-separated list of values, wrapped in parentheses.

Here’s an example:

let flight = ("LAX", 747)
print("We're flying to \(flight.0) in a \(flight.1)")

In the above code, the tuple is ("LAX", 747). You can clearly see two values, separated by a comma, wrapped in parentheses. In everyday coding, it’s easiest to recognize a tuple by its use of commas and parentheses.

The type of this tuple is (String, Int). The type of the first tuple value is String, and the second value’s type is Int. Again – separated by a comma, wrapped in parentheses.

In the previous example, we’ve also used syntax to get the values of a tuple. The tuple is a list, and we can get to its values by using indices 0, 1, etcetera. In the next section, we’ll look at more ways to deal with a tuple’s values.

Don’t confuse tuples with arrays, dictionaries or sets though! Tuples aren’t collections, but they do group values together. A difference with an array is that tuples values don’t need to have the same type. You can change a tuple’s values, provided it’s mutable with var. But, after a tuple is initialized, you can’t add any more items to it.

A tuple’s order can’t change after a tuple is initialized. So, the following two tuples don’t have identical types:

("LAX", 747) // Type is (String, Int)
(747, "LAX") // Type is (Int, String)

The order is important here. Even though the tuples contain the same values with the same type, the tuple types are different because their order is different.

You can compare tuples with each other if the tuple’s types are the same, and if the types themselves conform to the Equatable protocol. In other words, if you can compare a tuple’s values, you can compare the tuples themselves too.

Here’s an example:

let a = ("AMS", 737)
let b = ("LAX", 737)

a == b // Evaluates to "false", tuples are equatable

let c = ("AMS", "A330-800")
c == b // Compiler error, b/c tuple types themselves are different

In the first part of the above code, we’re comparing tuples with each other that have the same type, and types that conform to Equatable. The second example is a bit contrived, but obvious – you can’t compare incompatible types!

Tuple is pronounced “TEWple”, like “tuner” and “apple”. The word stems from the number 2, because a typical tuple has two values. You can use different names for tuples, such as single for a tuple with one value, and pair for two values, triple for 3 values, etcetera, but they’re most commonly referred to simply as “tuples”. In Swift, the null tuple, which is a tuple with zero values, is equal to Void.

Learn how to build iOS apps

Get started with iOS 13 and Swift 5

Sign up for my iOS development course, and learn how to build great iOS 13 apps with Swift 5 and Xcode 11.

Decomposing Tuples

You don’t have to reference a tuples values by their indices. You can use variable names instead! Let’s take a look at an example.

let flight = (airport: "LAX", airplane: 747, heading: 270)
print("We're flying a \(flight.airplane) towards \(flight.airport) with heading \(flight.heading) degrees.")

Interesting, right? We’re using syntax like flight.airport to get one of the values from the tuple. The tuple itself is defined with 3 names and 3 values, separated with colons and commas. This syntax is similar to how you get an object’s properties.

What if you didn’t define the tuple, but you still want to assign its individual values to distinct names? That’s where decomposition comes in. You can essentially “decompose” the tuple into separate variables or constants.

Like this:

let (airport, _, heading) = ("LAX", 747, 270)
print(airport)

Here’s what happens in the above code:

  • The tuple is ("LAX", 747, 270). It’s not assigned as a whole to a variable or constant, but instead its values are decomposed into separate constants.
  • We’re printing the airport constant, with its value "LAX". This value originates from the tuple, but it’s now a separate constant because of decomposition.
  • The underscore _ is a value from the tuple that we’re ignoring. This is typical Swift syntax that you may have seen before, for example in for loops with for _ in 1...5 {.

Consider, for example, that we’re using a function that’ll return a HTTP status code to us. Such a code typically consists of a number, like 404, and some text, like Not Found. The function is part of a framework, so we can’t change its code.

Here we go:

func getStatusCode() -> (Int, String)
{
return (404, "Not Found")
}

let (code, text) = getStatusCode()
print("The request returned with status code \(code) and said: '\(text)'")

See what’s happening there? The function returns a tuple of type (Int, String). Technically, the function returns one value – a tuple – which consists of two values, an integer and a string.

We want to access the individual tuple values, so we’re decomposing the tuple with (code, text). From there, we can use the individual constants code and text to print out the values. Awesome!

Decomposing a tuple can also be called “destructuring”, “destructing” or “deconstructing”. Whatever you call it – you’re taking the tuple apart!

Tuples In Everyday Swift Coding

Tuples may seem insignificant, but they’re quite useful in practical iOS development. We’ve already looked at a typical use case: returning more than one value from a function. What else can we do with tuples?

You can see tuples as if they’re tiny classes, that you can use without defining an actual class first.

Here, check this out:

class Flight {
    var airport:String
    var airplane:Int
}

let flight = Flight(airport: "AMS", airplane: 330)
print("We're going to \(flight.airport)...")

The above code first defines a class Flight, and then initializes an instance of that class, ultimately printing out flight.airport. We can do the same thing with tuples – with a whole lot less code.

let flight = (airport: "AMS", airplane: 330)
print("We're going to \(flight.airport)...")

Neat! And we can even enforce our tuple type by using a type alias, like this:

typealias Flight = (airport: String, airplane: Int)
let flight:Flight = ("HND", 737)
print("We're going to \(flight.airport)...")

On the first line of the above code, we’re creating an alias named Flight for the tuple type. From then on, we can use the tuple type itself and its alias interchangeably. On the second and third line, we’re setting the type of the flight to Flight, and print its value for airport.

What’s also interesting, is that you can use the the Flight type in the above code without also declaring the names of the tuple’s value. You can see this on the second line in the above code. The type is set to Flight and the tuple value is ("HND", 737) instead of (airport: "HND", airplane: 737). That’s much more concise!

And last but not least, tuples can be used to access the indices and values of array items by using the enumerated() function. Here’s how:

let drivers = ["Magnussen", "Raikkonen", "Hamilton", "Verstappen"]

for (index, name) in drivers.enumerated()
{
    print("\(name) has position \(index)")
}

In the above code, the function enumerated() on the drivers array returns a list of pairs – a tuple – with array indices and values. We’re decomposing that tuple with (index, name), so we can access the individual indices and values. Neat!

Fun Fact: Up to Swift 2.1, a function’s parameters were actually tuples, called tuple splats. After all, a function’s parameters are also written with parentheses, colons and commas. You can’t use this in Swift 5, though, because the syntax caused more harm than it did good.

Learn how to build iOS apps

Get started with iOS 13 and Swift 5

Sign up for my iOS development course, and learn how to build great iOS 13 apps with Swift 5 and Xcode 11.

Further Reading

Tuples are so simple, yet so powerful. Who would have thought that some values wrapped in parentheses could help you write code so productively?

In this article, we’ve discussed what tuples are and how you can use them in Swift. We’ve looked at decomposition, tuple types, and practical use cases for tuples in everyday iOS development.

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.