# Exercise: does Cancel preserve a reminder schedule?

Original illustrative example by Lukáš Soukup, with AI assistance. This is a
source-review exercise, not a simulator test result or a complete shipping app.

## Feature contract

The reminder summary belongs to the parent. Opening the sheet starts an edit.
Only Save may change the parent's schedule; Cancel must keep its earlier value.

## Code under review

```swift
import SwiftUI

struct ReminderReviewExercise: View {
    @State private var minutesBefore = 15
    @State private var isEditing = false

    var body: some View {
        VStack {
            Text("Reminder: \(minutesBefore) minutes before")
            Button("Edit schedule") { isEditing = true }
        }
        .sheet(isPresented: $isEditing) {
            ScheduleEditor(minutesBefore: $minutesBefore)
        }
    }
}

struct ScheduleEditor: View {
    @Binding var minutesBefore: Int
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        Form {
            Stepper("\(minutesBefore) minutes before", value: $minutesBefore, in: 5...60, step: 5)
            Button("Cancel") { dismiss() }
            Button("Save") { dismiss() }
        }
    }
}
```

## Supported finding

**Cancel keeps changes made to the reminder schedule.** Location:
`ScheduleEditor.body`, specifically the Stepper binding and Cancel action.

Start with 15 minutes, open Edit schedule, increment once and choose Cancel.
The required result is still 15 minutes; source tracing predicts 20. The
Stepper writes through the binding to parent state before either button is
pressed. Dismissal contains no operation that restores the earlier value.
The user can change a schedule while believing the edit was discarded.

**Evidence: source-traced.** The caller supplies its own state as the binding,
and the complete edit path is shown. These interaction steps have not been
executed as part of this example. Apple's state guidance documents the shared
write access provided by a binding; the save policy comes from this exercise's
feature contract, not from SwiftUI.

**Correction:** Edit a sheet-owned draft, assign it to the parent on Save and
discard it on Cancel. Decide whether swipe-to-dismiss should also discard the
draft, and include that path in the test.

**Next check:** Run Cancel and Save starting at 15 minutes, then repeat with
interactive sheet dismissal. Assert the parent summary after each path.

## Counterexample: immediate application is the contract

If a different feature explicitly applies every Stepper adjustment immediately
and its only close button says Done, writing through the binding can be correct.
The code pattern alone does not establish a defect. Verify the product's save
policy before reporting it. If that policy is absent, record an open question.

## Primary reference

- Apple: [Managing user interface state](https://developer.apple.com/documentation/swiftui/managing-user-interface-state)

## Related specialist resources

- [AvdLee's SwiftUI Agent Skill](https://github.com/AvdLee/SwiftUI-Agent-Skill)
- [Paul Hudson's SwiftUI Pro](https://github.com/twostraws/SwiftUI-Agent-Skill)
- [Swift Agent Skills directory](https://github.com/twostraws/swift-agent-skills)

These independently maintained projects provide broader guidance. This package
does not include their skill files, reference collections or examples.
