Episode #540

Fixing Persistent Sorting

Series: Todo App in SwiftUI

11 minutes
Published on October 14, 2022

This video is only available to subscribers. Get access to this video and 584 others.

In this episode we fix an issue that caused our sorting logic to be lost after adding persistence.

Todo Row Binding

    private func todoRowBinding(todo: Todo) -> Binding<Todo> {
        .init(get: {
            todo
        }, set: { mutatedTodo in
            let isToggleChange = mutatedTodo.isCompleted != todo.isCompleted
            if isToggleChange {
                handleToggleChange(mutatedTodo)
            } else {
                controller.update(mutatedTodo)
            }
        })
    }

Move And Update Indices


private func move(todos: inout [Todo], from source: IndexSet, to destination: Int) {
    todos.move(fromOffsets: source, toOffset: destination)
    todos.indices.forEach {
        todos[$0].sortOrder = $0
    }
}

Handle Toggle Change

private func handleToggleChange(_ todo: Todo) {
    guard let originalIndex = todos.firstIndex(where: { $0.id == todo.id }) else {
        controller.update(todo)
        return
    }
    var copy = todos
    copy[originalIndex] = todo
    for index in todos.indices.reversed() where index != originalIndex {
        if todos[index].isCompleted {
            continue
        }
        move(todos: &copy, from: .init(integer: originalIndex), to: index + 1)
        break
    }
    withAnimation {
        todos = copy
        controller.updateAll(copy)
    }
}

This episode uses Boutique 2.0, Xcode 14.0, Swift 5.7.