iOS development
UUID generation
Swift programming
GUID creation
Mobile app development

How to create a GUID/UUID using iOS

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

On iOS, generating a GUID or UUID is simple with Foundation APIs, but correct usage depends on lifecycle and persistence requirements. Some identifiers should be ephemeral per event, while others must remain stable across app sessions. This guide covers generation, formatting, persistence, and validation patterns in Swift and Objective-C.

Generate UUID Values in Swift

Swift provides UUID, which creates random version-4 UUID values suitable for most application-level identity use cases.

swift
1import Foundation
2
3let id = UUID()
4print(id)                // typed UUID value
5print(id.uuidString)     // uppercase string with hyphens

Each call returns a new value. Collision probability is negligible for normal app workloads.

Generate UUID Values in Objective-C

Objective-C uses NSUUID, which is equivalent for practical purposes.

objective-c
1#import <Foundation/Foundation.h>
2
3NSUUID *uuid = [NSUUID UUID];
4NSString *uuidString = [uuid UUIDString];
5NSLog(@"%@", uuidString);

If your project mixes Swift and Objective-C, exchange values as strings at module boundaries and parse into typed UUIDs where possible.

Decide Whether Identifier Should Persist

A common mistake is generating a new identifier every launch even when business logic requires stability. Define the lifetime first.

  • Event correlation ID: create new UUID per action.
  • Local record primary key: create once per record.
  • App instance identifier: generate once and persist.

Persisting a non-sensitive app-scoped identifier can be done with UserDefaults.

swift
1import Foundation
2
3enum AppInstanceId {
4    private static let key = "app.instance.id"
5
6    static func getOrCreate() -> String {
7        let defaults = UserDefaults.standard
8        if let existing = defaults.string(forKey: key) {
9            return existing
10        }
11
12        let newId = UUID().uuidString
13        defaults.set(newId, forKey: key)
14        return newId
15    }
16}
17
18print(AppInstanceId.getOrCreate())

If identifier confidentiality matters, use Keychain storage instead.

Normalize Formatting for External Contracts

Backends sometimes require lowercase or compact form without hyphens. Normalize at integration boundaries, not everywhere.

swift
1import Foundation
2
3let raw = UUID().uuidString
4let lower = raw.lowercased()
5let compact = lower.replacingOccurrences(of: "-", with: "")
6
7print(raw)
8print(lower)
9print(compact)

Keeping one internal canonical form avoids comparison and logging inconsistencies.

Keep UUID Typed in Data Models

Using UUID in your model improves type safety and reduces accidental format bugs.

swift
1import Foundation
2
3struct TodoItem: Codable {
4    let id: UUID
5    var title: String
6    var done: Bool
7}
8
9let item = TodoItem(id: UUID(), title: "Ship release", done: false)
10let encoded = try JSONEncoder().encode(item)
11let decoded = try JSONDecoder().decode(TodoItem.self, from: encoded)
12print(decoded.id.uuidString)

Convert to string only when crossing process or storage boundaries.

Validate Incoming UUID Strings

When accepting identifier input from APIs, deep links, or external systems, validate before use.

swift
1import Foundation
2
3func parseUUID(_ value: String) -> UUID? {
4    return UUID(uuidString: value)
5}
6
7print(parseUUID("550E8400-E29B-41D4-A716-446655440000") != nil)
8print(parseUUID("not-valid") != nil)

Failing early at validation boundaries prevents confusing downstream errors.

Correlation IDs for Logging and Tracing

UUIDs are excellent for request tracing.

swift
1import Foundation
2
3func makeHeaders() -> [String: String] {
4    let correlationId = UUID().uuidString
5    return ["X-Correlation-Id": correlationId]
6}
7
8print(makeHeaders())

Consistent correlation IDs make multi-service debugging much faster.

Common Pitfalls

  • Regenerating IDs when a stable persisted identifier is required. Fix: define ID lifetime and persist accordingly.
  • Storing sensitive identifiers in plain UserDefaults. Fix: use Keychain for confidentiality requirements.
  • Mixing uppercase, lowercase, and compact forms throughout the codebase. Fix: keep a canonical internal representation and normalize at boundaries.
  • Treating UUID as an authentication secret. Fix: use proper auth tokens for security and UUID only for identity references.
  • Using raw strings in domain models. Fix: keep UUID type in model structs and parse at input points.

Summary

  • Use UUID() in Swift or NSUUID in Objective-C for iOS GUID generation.
  • Define whether each UUID should be ephemeral or persisted.
  • Normalize format only where external systems demand it.
  • Prefer typed UUID properties in app models.
  • Validate inbound strings early and use correlation IDs for observability.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.