Back to course overview
Module 4Data & persistence 25 min

Lab: Persist and fetch real data

Harden persistence with sample data and a query filter, and write your first standalone async networking function.

Outcome of this lab

Confidence that your data survives relaunch under real use, plus a reusable async function you'll evolve into the AI call next module.

Step 1 — Prove persistence under stress

  1. 1Run the app and add five entries with distinct text.
  2. 2Fully quit the app (stop it with Xcode's ■ button and press ⌘R again — just backgrounding it isn't a real relaunch).
  3. 3Confirm all five return in the right order. Edit one, relaunch, confirm the edit persisted.

Step 2 — Add a search filter (optional but instructive)

Ask your assistant to add a search field to EntryListView that filters entries by body text using a SwiftData #Predicate. This teaches you how queries narrow results:

Prompt to try

In my EntryListView (iOS 17+, SwiftData), add a searchable text field that filters the @Query results by whether body contains the search text, case-insensitive, using #Predicate. Show me the diff, not the whole file.

A diff is just the list of lines to add (+) and remove (−) — much easier to review than a whole regenerated file. If applying one by hand feels confusing, ask for the full file instead.

One heads-up on the result: expect the assistant to move the @Query into a small subview whose initializer takes the search text. That's the correct SwiftUI pattern for a query that depends on changing state — not a mistake.

Step 3 — Write a standalone async fetch

  1. 1Create QuoteService.swift and paste the fetchQuote() function from the lesson.
  2. 2Add a temporary button somewhere that calls it in a Task and prints the result: let quote = try await fetchQuote() followed by print(quote.quote).
  3. 3Run it, tap the button, and watch a real network response appear in Xcode's console (View ▸ Debug Area ▸ Activate Console if it's hidden). You've now made a live API call from your app.

If this quote API is ever down, don't let it block you — ask your AI assistant for another free JSON API that needs no key, and adjust the Quote struct's fields to match what it returns.

Keep the async muscle memory

The async throws function + Task { await } call site is the exact structure your AI feature uses next module — only the URL, request body, and response type change. If this lab feels comfortable, Module 5 will too.

bashbash
git add .
git commit -m "Persistence hardening + first async network call"