Tuples in Swift

Milos Malovic
4 min readFeb 5, 2020

--

Two years ago, when I started with iOS, I didn't know what the tuples are, why and where I would use them. In few weeks later, I realized that I am actually using them everywhere, I just didn't know that.

Little example :

func willDoNothing() {}

Sometimes even accidentally you run func that do nothing, and what compiler says about that. Compiler returns () , an empty tuple.
Swift is mapping void return types in tuples.

Tuples do not have a formal definition, not a clear one, but there are easy to create and very easy to use. They are like lightweight structs.

There are downsides of tuples, they can't implement methods and protocols. And like every other in swift tuples are safety typed when you create tuple you cannot just change its type.

Here is a basic one 👇🏻

let client = (fullName: "SomeName", isActive: Bool, age: Int)
// you will access elements like this
fullNameTextField.text = client.fullName

Thanks, Good, that we do not belong to the era when guys access those elements with typecasting after returning arrays and don't bother to do that,
it is totally messed 😩

Pattern matching with tuples:

let bankClient = (clientType: "Company", isPremiumClient: true)switch bankClient {
case let(type, false):
print("client type is \(type) and it is not a premium client" )
default:
break
}
// or you can ignore tuple elementsswitch bankClient {
case let (type, _):
print("client type is \(type)" )
default:
break
}

Here is a little advanced topic with closures:
Even if you cannot add a method to the tuple, you can add the closure 👇🏻

let client = (name: "John", bankNumber: "01234567890", cardType: "Visa", withdrawalAmount: { (cash: Double) in
print("amount \(cash)")
})

To be honest, I do not remember even ones I did this in real-life situations, but it is ok to know this will work, but there is one problem with closures and tuples together if we can call it a problem. You cant access some of the elements in this manner…👎🏻

print("my name is \(client.name, client.withdrawalAmount)")
// this code won't compile

So where are they used the most?

Like in other articles that covered this topic I would say the same:
When you need a func that will return multiple value types.
But what does that mean, when will be that in real life.

Probably you won't write anything like this:

func someClient() -> (name: String, age: Int, havePremiumAccount: Bool) {
return ("John", 27, true)
}

But in at least 50 % of app you will have something like this 🙄


func fetchBankClient(id: Int) -> (client: Client, havePremiumAccount: Bool, accountNumber: String) {
///
}
let client = fetchBankClient(id: 1054)
// then you will probably update UI with this data or create some API call to send some data to server.
Something like this:
if client.havePremiumAccount == true {
showFastCreditView = true
}

This is cool, but swift have even better way doing this 😌

let (client, havePremiumAccount, accountNumber) = fetchBankClient(5)
// in swift this is calling destructuring tuple.
//
Now we have 3 new variables that you can access more easily.
// And it looks more readable.

Just to summarize this, in most of cases you will use tuples as result types of API calls, with swift result types and escaping closures …

func getClients(objectToPass: Object, completion:@escaping (SomeType, Error) → ReturnType)

Typealias and tuples:

Tuples are great for this functionality, it is much easier to write functions that have tuples as return type if you make them like this.
Tuples can be very long and can repeat many time in the same method.

Example:

typealias UserDestination = (destination:(latitude: Double, longitude: Double))
func showOnMap() -> UserDestination {
}

Real-world example:

protocol URLSessionProtocol {
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> ()
func dataTask(request: URLRequest, completionHandler: @escaping
DataTaskResult) -> URLSessionDataTask
}

Something else that I can mention is an optional tuple ❓

let client : (String, Bool)? = ("Milos", true)
// this tuple is optional tuple
let client: (String, Bool?) = ("Milos", nil)
// this tuple have optional elements

Last is interview test tip that can be done with tuples, and it will get you more points for sure :)

We all know about fizzbuzz test… You will get an array of numbers and you will need to check what number is equal divisible by the other two numbers, in most cases is 3 and 5.

let numbers = [Int]()
for i in 1...100 {
numbers.append(i)
}
// now we have array that contains Integers from 1 to 100.
// in most cases you will do for loop then if statement, and that is // totally ok 🙄
// But here is a cool one 🤗
func fizzBuzz(number: Int) {
switch (number % 3 == 0, number % 5 == 0) {
case (true, false):
print("Fizz")
case (false, true):
print("Buzz")
case (true, true):
print("FizzBuzz")
case (false, false):
return
}
}
for i in numbers {
fizzBuzz(i)
}

Conclusion

I hope you enjoyed this, if there is anything unclear about this, or you have something else that is cool 😎 or really advanced about this topic please comment…

--

--