Swift’s Foundation UUID type wraps a 128-bit RFC 4122 value and generates UUID v4 by default. For most iOS, macOS, and server-side Swift use cases this is fine. When you need chronologically sorted records — for CloudKit sync, SwiftData queries, or server APIs — UUID v7 provides sortable IDs without a separate timestamp column. The motivation is the same as in any other language: as documented on Wikipedia’s UUID article — Version 7, the timestamp prefix keeps B-tree indexes sequential.

Foundation UUID — the built-in option

import Foundation

// Generate a UUID v4
let id = UUID()
print(id.uuidString)    // "550E8400-E29B-41D4-A716-446655440000" (uppercase)
print(id)               // same — UUID conforms to CustomStringConvertible

// Parse from string
if let parsed = UUID(uuidString: "018fbe3a-4c5d-7b12-8abc-0123456789ab") {
    print(parsed.version) // not built-in — see below
}

// Raw bytes (uuid is a 16-element tuple of UInt8)
let bytes = id.uuid

Foundation’s UUID does not expose a .version property. To read the version digit:

extension UUID {
    var version: Int {
        // Byte 6 contains version in high nibble
        Int(uuid.6 >> 4)
    }
}

UUID v7 in Swift

The swift-uuid-v7 package (also available as a Swift Package from github.com/nickvdyck/uuid-v7-swift) generates RFC 9562-compliant UUID v7 values and returns a Foundation UUID, making it a drop-in replacement wherever UUID() is used today.

Add the package via Swift Package Manager:

// Package.swift
dependencies: [
    .package(url: "https://github.com/nickvdyck/uuid-v7-swift", from: "1.0.0")
],
targets: [
    .target(name: "MyApp", dependencies: ["UUIDv7"])
]

Usage:

import UUIDv7

let id: UUID = UUIDv7()   // Returns a Foundation UUID with v7 content
print(id.version)         // 7 (using the extension above)
print(id.uuidString)      // "018fbe3a-4c5d-7000-8abc-0123456789ab"

Because UUIDv7() returns the standard UUID type, it works anywhere UUID() works — SwiftData models, Core Data attributes, Codable structs, and API responses.

SwiftData with UUID v7

import SwiftData
import UUIDv7

@Model
final class Order {
    @Attribute(.unique) var id: UUID
    var totalCents: Int
    var createdAt: Date

    init(totalCents: Int) {
        self.id = UUIDv7()               // time-sortable primary key
        self.totalCents = totalCents
        self.createdAt = Date()
    }
}

With UUID v7 as the id, a SwiftData FetchDescriptor sorted by id gives chronological order — no separate sort descriptor on createdAt needed:

let descriptor = FetchDescriptor<Order>(
    sortBy: [SortDescriptor(\.id)]       // chronological — v7 sorts by time
)
let orders = try context.fetch(descriptor)

Core Data with UUID v7

In the Core Data model editor, set the attribute type to UUID. In your NSManagedObject subclass:

import CoreData
import UUIDv7

extension Order {
    @nonobjc class func newOrder(in context: NSManagedObjectContext) -> Order {
        let order = Order(context: context)
        order.id = UUIDv7()   // time-sortable; sorts correctly in fetch requests
        return order
    }
}

A NSSortDescriptor(key: "id", ascending: true) on a Core Data fetch request will return records in insertion order because UUID v7 sorts chronologically as a string.

Codable and API responses

Foundation’s UUID encodes as a lowercase hyphenated string in JSONEncoder by default. No extra configuration is needed — UUID v7 values round-trip through Codable identically to v4:

struct UserResponse: Codable {
    let id: UUID       // encodes as "018fbe3a-4c5d-7b12-8abc-0123456789ab"
    let email: String
}

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(UserResponse(id: UUIDv7(), email: "a@b.com"))

When to keep using UUID v4

UUID v7 embeds a 48-bit creation timestamp readable by anyone with the ID. For user-facing tokens, share links, or any UUID appearing in URLs or client-visible JSON, use UUID() (v4) instead. The CloudKit documentation recommends opaque record IDs for publicly-shared resources — another case where v4 is preferred. See UUID v4 vs UUID v7 for the full trade-off analysis.

External references

Frequently asked questions

How do I generate a UUID in Swift?

Use UUID() from the Foundation framework. It generates an RFC 4122 UUID v4 using the platform CSPRNG. The value is available as a string via uuid.uuidString (uppercase, hyphenated) or as raw bytes via the uuid tuple property. No import is needed — Foundation is available in all Apple platforms.

Does SwiftData support UUID primary keys?

Yes. Mark a property with @Attribute(.unique) and type it as UUID to use it as a stable identifier. SwiftData uses the Foundation UUID type, which produces UUID v4 by default. For UUID v7, generate the value in the model's initializer using a third-party package and assign it to the UUID-typed property.

How is UUID stored in Core Data?

Core Data has a native UUID attribute type (available since iOS 11 / macOS 10.13). It stores the value as 16 bytes internally. You can access it from Swift as a UUID? optional. Avoid storing UUIDs as String attributes — they use more space and lose type safety.