How To Generate a Random Unique Identifier with UUID in Swift


Aasif Khan
By Aasif Khan | Last Updated on December 22nd, 2021 6:32 am | 4-min read

Random unique identifiers (UUIDs) are super useful in Swift programming. Imagine you’re storing objects in a database, and every object needs a unique ID. The generated ID needs to be unique, universally, across all devices, all users, all objects in the database. How do you generate such an ID?.

Generating Random Identifiers with UUID

The term UUID stands for Universally Unique Identifier. In Swift, we can generate UUIDs with the UUID struct.

Here’s how:

let identifier = UUID()
print(identifier)
// Output: 8D31B96A-02AC-4531-976F-A455686F8FE2

The UUID() initializer generates 128 random bits. Because the UUID struct conforms to the CustomStringConvertible, we can print it as a string.

If you want to get the UUID string directly, you can use the uuidString property directly. Like this:

print(identifier.uuidString)

Let’s move on to find out how these identifiers actually work!

The UUID struct also conforms to Hashable, so you can use UUIDs in a Set.

What’s RFC 4122?

Identifiers that are generated with UUID are universally unique identifiers. This means that the chance of generating the same identifier twice, on any device on the planet, is basically zero!

How so? Let’s look at a bit of history, to find out.

Many of the world’s tools, technologies, mechanisms and products are based on standards. A standard for length is the meter, for instance. The meter isn’t just something we agreed on, it’s actually based on the speed of light.

A meter is exactly the same as the distance light travels in a vacuum in 1 / 299 792 458 second. The speed of light is constant, so it doesn’t change. Provided you can measure it, you can always figure out how long a meter exactly is, regardless of where you are. That’s the beauty of standards!

Some standards aren’t as spectacular. Take for instance RFC 4122. This document describes the standard for universally unique identifiers. It’s created in 2005 by computer scientists, and published as an RFC (“Request For Comments”) by the Internet Engineering Taskforce (IETF).

In the technology community, an RFC is a publication from computer scientists. It’s like saying: “Look, we’ve come up with this and that, would you please comment on it?” The publication is peer-reviewed by other scientists, who check it for accuracy and all sorts of mistakes. Some RFCs are then adopted by institutions like the IETF.

They’ve basically scienced the sh*t out of it!

When an RFC is published, it doesn’t immediately become a standard. Some institutions adopt it as a standard anyway, such as Apple using RFC 4122 in the implementation of UUID. The IETF isn’t the only institude that publishes RFCs and accepts some as standards, other institutions are ISO, IEC and W3C, for example.

It’s worthwhile to know that these organizations do good work, and that there’s a rigorous process for determining what’s standard and what not. Thanks to the standardization of things like HTML, the meter and UUIDs, we unequivocally know how to properly measure, implement and format the tools we’re working with.

Let’s get back to UUIDs!

RFC 4122 looks scary, but try reading through it – it’s not that scary at all. You’ll read a lot about what the format exactly is, and the appendices even include a few programming examples..

UUIDs: Universally Unique Identifiers

A UUID is composed of 128-bit number, so 128 ones and zeroes. It has a so-called canonical textual representation, that looks like this:

123e4567-e89b-12d3-a456-426655440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

Let’s take a closer look:

  • A UUID consists of 16 octets, i.e. 16 groups of 8 bits (16 × 8 = 128), that are represented as 32 hexadecimal digits, displayed in 5 groups, separated by hyphens (-).
  • Just as a decimal digit goes from 0 to 9, a hexadecimal digit runs from 0 to F. It’s like an alphabet with 16 characters: 0123456789ABCDEF. Why use it? It’s simpler to encode a UUID as 32 textual characters than as 128 ones and zeroes.
  • The third and fourth group have special M and N placeholders that indicate the version and variant of the UUID algorithm. That’s smart! A reference to which algorithm we used to encode the UUID is baked right in.

As a software developer, it’s worthwhile to learn about binary, decimal and hexadecimal number systems. The RGB color space, for example, uses hexadecimals to express colors!

On iOS, we’re most interested in RFC 2144 version 4. The earlier versions of the universally unique identifiers relied on date-time, device MAC address and namespace identifiers to generate unique IDs. Version 4 relies on randomness.

Whenever the UUID struct generates a new ID, it basically does 122 dice rolls to come up with 122 random bits. (Some of the 128 bits are used for version and variant indicators).

A quick bit of math tells us that this leads to 2122 = 5.3×1036 different UUIDs, equivalent to 5.3 undecillion IDs, or 5.3 trillion trillion trillion, or a 5.3 followed by 36 zeroes. That’s a lot of identifiers…

What are the odds of generating two of the same IDs? Here’s a quick comparison:

  • The number of IDs you need to generate to have a 50% chance of collision (i.e., two of the same IDs) is 2.71 quintillion, or 2.71×1018
  • It would take you 85 years to do this, if you generate 1 billion IDs per second
  • To save all those IDs, you’d generate a file of about 45 exabytes, or 45 million terabytes, which is much more than the largest databases in the world
    (Source)

In every practical sense, it’s safe to assume that UUID is universally unique, across all devices, databases, iPhones, etc. in the world. The chance of generating the same UUID twice is negligible.

And a cool thing is that, if we have larger, more powerful computers in the future, we just add one bit and end up with twice the amount of potential UUIDs!

UUIDs in Practical iOS Development

The most practical use for UUIDs in iOS development is in databases. Consider that you’re storing user data in a database. Every user needs a unique ID, so you can reference the user in queries and APIs.

Here’s an example:

class User {
var identifier:UUID
var username:String
var email:String
}

You could create a new User object like this:

var user = User(identifier: UUID(), username: “arthur42”, email: “[email protected]”)

You could also create a User factory, to abstract away the responsibility of generating new UUIDs. Like this:

class UserFactory {
func createUser() -> User {
return User(identifier: UUID(), username: “”, email: “”)
}
}

It might be smarter to save UUIDs as strings, especially if you want to format user data as JSON or send it to a webservice API. Like this:

class User {
var identifier:String

}

let user = User(identifier: UUID().uuidString, )

It’s inconvenient to encode raw bytes in data that’s stored as strings, such as JSON. It’s simpler to use strings, although the database you’re using might store and query raw bytes more efficiently than strings.

Many webservices and APIs can generate unique identifiers for you, so you won’t have to worry about their implementation as much. Like Firebase, for example, creates its own UUIDs automatically:

let ref = database.child(“Users”).childByAutoId()

And that’s all there is to it!

Further Reading

As always, diving deeper into an iOS development topic uncovers a wealth of information. It’s fascinating to see how RFCs work, in light of generating unique identifiers, and to find out how we can ensure they’re unique. With science!


Aasif Khan

Head of SEO at Appy Pie

App Builder

Leave a Reply

Your email address will not be published. Required fields are marked *

Most Popular Posts