Note: This entire blog post can be downloaded as a Swift playground. Feel free to experiment!

Swift brings a couple new things to iOS and Mac development, one of which is tuples. Tuples are a pretty nifty programming construct that have been around for a while, and are common in languages like Python. Pronounced either two-ple or tuh-pul(if you’re a Python dev this is the only way to pronounce it, the alternative is blasphemy), tuples are simply ordered sets of values and for our purposes they group multiple values into a single compound value.

Why is this important? In Objective-C, if you want a method to return more than one value you have two options – return a custom object with properties that store your return values or stick those values in a dictionary. With Swift however, we can use tuples to return more than one value. The values in a tuple can be of any type and don’t have to be the same type as each other. Despite being somewhat simple, you can actually do quite a few things with tuples.

Unnamed Tuples

To create a basic tuple, all we do is group values between parentheses and separate them by commas.

let latLong = (48.8582, 2.2945)

We’re taking two values of type Double and grouping them into a single tuple value. Swift infers the type so we don’t have to specify it but we could also write it as

var anotherLatLong: (Double, Double) = (48.8582, 2.2945)

Note that since we used let in the first case, we created an immutable, or unchangeable tuple, whereas the latter case is a mutable tuple since we used var.

Now that we have a compound value, how do we access it? You have two options:

  • By index
let latitude = latLong.0
let longitude = latLong.1
  • Decomposing the tuple by name
let (latitude, longitude) = (48.8582, 2.2945)
latitude //48.8582
longitude //2.2945

The first option is convenient if we need to access our tuple values quickly, but being able to assign the values to variables/constants lets us use tuple values throughout our code. This leads us to the second type of tuple.

Named Tuples

We don’t need to go through the whole charade of creating an unnamed tuple and subsequently decomposing it to named variables, we can do that from the start.

let coordinates = (latitude: 48.8582, longitude: 2.2945)

Now to access the values we can use the convenient dot syntax.

coordinates.latitude //48.8582
coordinates.longitude //2.2945

Tuples as Return Values

Let’s say that we’re given a time interval and we need to figure out the equivalent number of minutes and seconds. In Objective-C my options are to return a struct that stored the minute and second value, or use a dictionary. Let’s look at how we can accomplish that in Swift.

func timeElapsed(interval: Double) -> (minutes: Int, seconds: Int) {
    var minutes = Int(floor(interval/60))
    var seconds: Int = Int(trunc(interval - Double(minutes * 60)))
    return(minutes: minutes, seconds: seconds)
}

We define a named tuple as the return value for our method and pass in the calculated minutes and seconds. Accessing the tuple values using dot syntax allows for some really concise code

let minutes = timeElapsed(250).minutes

Pretty cool huh? As you use Swift more, try and be “Swifty “ and use some of these newer concepts rather than sticking to the Objective-C way of doing things.

We can take it one step further and combine tuples with pattern matching in a switch statement to do some cool things. Let’s say we had a time interval in seconds that we wanted to display as a string in the format “xx min xx sec”, i.e., 01 min 15 sec. Using the method we just wrote:

func timeAsLongStyle(interval: Double) -> String {
    let (min, sec) = timeElapsed(interval)
    switch (min, sec) {
    case (0, 0..<10):
        return "0\(sec) sec"
    case (0, 10..<60):
        return "\(sec) sec"
    case (_ , 0..<10):
        return "\(min) min 0\(sec) sec"
    default:
        return "\(min) min \(sec) sec"
    }
}

First we store the value we get from the timeElapsed method as a tuple and then switch on the tuple value. In the first case case(0, 0..<10) we are checking to see if the minute value is zero and the second value is between 0 and 9. If it is we only return the second value with a zero appended. Using a tuple lets us compare multiple values in a single switch statement. Let’s skip over the second case because it’s fairly easy to understand what’s going on there.

The third case is quite interesting. When the second value is below 10, we want to append a 0 in the string representation regardless of the minute value. In the tuple, by specifying an underscore for the minute value, we can chose to disregard it when pattern matching. In this case what we’re saying is regardless of the minute value as long as the second value is below 10, throw a zero in there.

Seemingly simple, tuples allow us to write more concise code and build more useful functions. If you want to learn more about Swift and how to use Swift in iOS development, including more about tuples, structs, enums, check out the iOS development with Swift track on Treehouse!