Sorting

Use SortDescriptor to define the order of query results.

Basic Sorting

// Sort by name ascending (default)
let byName = SortDescriptor<User>(propertyName: "name")

let users = try context.fetch(
    FetchDescriptor<User>(sortBy: [byName])
)

Sort Order

// Ascending (A-Z, 0-9, oldest first)
let ascending = SortDescriptor<User>(
    propertyName: "name",
    order: .forward
)

// Descending (Z-A, 9-0, newest first)
let descending = SortDescriptor<User>(
    propertyName: "createdAt",
    order: .reverse
)

Multiple Sort Criteria

Sort by multiple properties - earlier sorts take precedence:

// Sort by lastName, then firstName
let descriptor = FetchDescriptor<User>(sortBy: [
    SortDescriptor(propertyName: "lastName"),
    SortDescriptor(propertyName: "firstName")
])

// Using builder pattern
let descriptor = FetchDescriptor<User>()
    .sorted(by: SortDescriptor(propertyName: "lastName"))
    .sorted(by: SortDescriptor(propertyName: "firstName"))

Reversing Sort Order

let byName = SortDescriptor<User>(propertyName: "name")

// Get the reversed version
let byNameDesc = byName.reversed

Common Patterns

Most Recent First

let recentFirst = FetchDescriptor<Post>()
    .sorted(by: SortDescriptor(propertyName: "createdAt", order: .reverse))
    .limit(10)

Alphabetical

let alphabetical = FetchDescriptor<User>()
    .sorted(by: SortDescriptor(propertyName: "name", order: .forward))

By Priority Then Date

let tasks = FetchDescriptor<Task>()
    .sorted(by: SortDescriptor(propertyName: "priority", order: .reverse))
    .sorted(by: SortDescriptor(propertyName: "dueDate", order: .forward))

Sort Order Enum

Value SQL Description
.forward ASC Ascending order (default)
.reverse DESC Descending order

NULL Handling

NULL values are typically sorted last in ascending order and first in descending order, following SQL conventions.

Next Steps