Project 2 — Checklist: the specswift-6.4/ios-26
Lesson 1 / 5
Unit 22 · Checklist

Project 2 — Checklist: the spec

Note

Unit 22 · Project 2. A Reminders clone — multiple lists, due dates, priority, flags, notes, search, and Today/Scheduled/Flagged smart views. Backend Tier 1 (on-device persistence with SwiftData). AI stage still Tutor — you hand-type, /tutor hints only. This spec defines the target; the milestones build it.

Project 1 lived entirely in memory. Project 2 makes data outlive the app launch and gives it real structure. You build an app a person could actually run their week on: reminders grouped into lists, each with a due date, a priority, a flag, and notes; smart views that gather what's due today or everything you've flagged; and search across the lot. All of it persists, and it's driven by a SwiftData object graph with a relationship — lists own reminders, and deleting a list takes its reminders with it.

What you build

Checklist — a Reminders app with three surfaces:

  • A home screen: four smart tiles (Today, Scheduled, Flagged, All) with live counts, your lists below with per-list counts, and a search field.
  • A list / smart view: the reminders in a list or a smart filter, split into active and completed, each row showing its due date, priority, and flag. Complete on tap, swipe to flag or delete, tap to edit, and add new reminders.
  • A reminder detail editor: title, notes, a flag, an optional due date, a priority, and which list it belongs to.

The screens

Screen Shows Key interaction
Home smart tiles + your lists with counts, search tap a tile or list; search
List / smart view reminders with due date, priority, flag; active + completed complete, swipe to flag/delete, tap to edit, add
Reminder detail title, notes, flag, due date, priority, list edit any field

What it looks like finished

Reminders home — Today/Scheduled/Flagged/All smart tiles with counts and My Lists A list of reminders with due dates, priority markers, and flags The Today smart view gathering everything due today across lists The reminder editor — notes, flag, due date, priority, and list
The finished build in the simulator: the home with smart tiles and lists, a list of reminders (due dates, priority markers, flags), the Today smart view gathering due items across lists, and the reminder editor. Everything is SwiftData-backed and survives relaunch.

Concepts this locks in

  • The @Model macro and a SwiftData relationship (ReminderListReminder) with a cascade delete.
  • @Query to fetch and auto-observe; modelContext to insert and delete.
  • Deriving smart views (Today, Scheduled, Flagged) by filtering the model over date and boolean fields.
  • .searchable over the persisted store.
  • List + ForEach, active/completed sections, swipe actions, and a real empty state.
  • @Bindable two-way editing of a persisted object, including DatePicker and a relationship Picker.
  • .modelContainer wiring at the app root with more than one model type.

Backend tier: 1

Tier 1 means local persistence — data stored on device, surviving relaunch, no server. SwiftData is Apple's modern answer (the successor to Core Data), and it's the correct tool: a structured, single-device object graph with a relationship and live-updating queries. You'll feel how little code the relationship and the smart-view filters take compared to what this cost before.

AI stage: Tutor

Same discipline as Project 1: you write every line, /tutor gives concept-level hints, never pasteable code. SwiftData has sharp edges (where the container is attached, how a relationship is declared, why a query doesn't update, when a save happens). When you hit one, ask /tutor a specific question and close the gap yourself. This is the last project before the AI stage relaxes to Pair — earn the fundamentals now.

Tip

Build the model layer first and prove it saves before you make the UI pretty. Get the ReminderListReminder relationship and the container right, then layer on dates, priority, and the smart views. A Reminders app that persists reliably and looks plain beats one that looks great and loses your data on the second launch.

In scope

  • Multiple lists, each with a name, symbol, and colour, on a SwiftData relationship.
  • Reminders with title, notes, done state, an optional due date, a priority, and a flag.
  • Smart views — Today, Scheduled, Flagged, All — derived by filtering the store.
  • Search across titles and notes.
  • Add, complete, edit, delete; active/completed sections; a designed empty state; light and dark both correct and VoiceOver-navigable.

Out of scope

  • iCloud sync and sharing (that's higher-tier work; the store is local).
  • Actually delivering notifications, location reminders, and recurring/repeat rules.
  • Subtasks, tags, and attachments.
  • Drag-to-reorder and custom smart-list rules (worthy stretch goals, not requirements).

Definition of done

You create a list, add reminders with due dates, priorities, and flags, complete a couple and watch the counts update, edit one in the detail editor, delete one by swiping, confirm Today and Flagged gather the right reminders across lists, search finds an item by a word in its notes, then force-quit, relaunch, and everything is still there. Then the rubric.

Knowledge check

Q: Why is SwiftData the right persistence tool here rather than writing JSON to a file? The data is a structured, single-device object graph with a relationship that the UI must observe live. SwiftData gives you the @Model graph, the relationship with its cascade delete, automatic change tracking, and @Query that updates the view for free — hand-rolled JSON gives you none of that and grows brittle the moment you add lists.

Q: What is Tier 1, and what does it deliberately exclude? Tier 1 is on-device persistence: data survives relaunch, no server involved. It excludes sync and networking — those belong to higher tiers (Tier 2+) in later projects — as well as the OS-level delivery of notifications.