SkyWatch — Requirements

Personas

  • Casual checker — opens the app once a day, wants to know if it’s going to rain. Sees the home screen, leaves. Should be sub-5-second-experience.
  • Outdoor planner — checks the hourly forecast before deciding to go for a run, picks a saved location near the trailhead, checks precipitation map. Should be sub-15-second.
  • Severe-weather watcher — has notifications on, wants Lock Screen widget to surface the alert immediately and an in-app deep dive into the alert details.

User stories

Onboarding

  1. As a first-time user, I see a single screen explaining what SkyWatch does and tap “Get Started,” which triggers the location permission prompt with a clear NSLocationWhenInUseUsageDescription.
  2. If I deny location, the app falls back to a search bar where I can type a city. Denial is not a dead-end.
  3. After granting permission, I land on the home screen showing the current location’s weather within 2 seconds (cached if possible).

Home

  1. The home screen shows: current temperature, condition icon, “feels like,” 24-hour scrubbable timeline, next 7 days, and the WeatherKit attribution badge per Apple’s requirement.
  2. The timeline updates the displayed hour as I scrub; numbers don’t flicker.
  3. I can swipe left/right to switch between my saved locations.
  4. Pull-to-refresh forces a fresh WeatherKit call (subject to a 5-minute minimum interval to protect the budget).

Saved locations

  1. I can tap “+” to add a saved location via map pin drop, search, or “Use My Current Location.”
  2. Saved locations sync via CloudKit private DB across my devices automatically; I do not have to log in (CloudKit uses my Apple ID).
  3. I can reorder and delete saved locations. Deletion is immediate, no undo (matches Apple Weather).
  4. If sync fails (network, quota), the app shows a non-modal status indicator, never blocks the UI.

Map

  1. From a saved location, I can tap “Map” to see a MapKit view centered on that location with a heatmap overlay for precipitation in the next hour.
  2. The overlay scrubs forward in 5-minute intervals via a slider at the bottom.
  3. Annotations show nearby saved locations as smaller pins so I can quickly switch.

Widgets

  1. A Lock Screen widget (accessoryCircular and accessoryRectangular) shows the next-hour precipitation chance.
  2. A Home Screen widget (systemSmall and systemMedium) shows the current temperature, condition icon, and high/low.
  3. Widgets refresh at most every 15 minutes and use cached forecast data; they never call WeatherKit directly from the widget extension.
  4. If the data is stale > 6 hours, the widget shows “Tap to refresh” rather than fake data.

App Intents

  1. The Shortcut “Get weather for [location]” returns the current temperature, condition, and the next hour’s precipitation chance.
  2. The Shortcut works without launching the app (background execution allowed by intent).

Alerts

  1. If WeatherKit reports any severe alert for a saved location, the user receives a local notification using UNUserNotificationCenter keyed to the alert ID (to avoid duplicates).
  2. Tapping the notification deep-links to the alert detail screen.

Acceptance criteria

  • Cold-start to home screen with cached data: < 2 seconds on iPhone 13.
  • Cold-start to home screen with fresh data: < 5 seconds on a typical LTE connection.
  • Widget refresh failure rate: < 1% over a 7-day window (measure via os_signpost + a debug counter).
  • WeatherKit calls per user per day: < 8 under normal use (cache hit rate > 80%).
  • CloudKit sync conflict rate (locations modified concurrently on two devices): handled gracefully — last-writer-wins with a logged audit trail.

Non-goals

  • No paid tier. WeatherKit’s free quota is the limit; no monetization in this capstone.
  • No social features (no sharing locations between users, no comments).
  • No precipitation forecasts beyond 1 hour for the map (WeatherKit’s minuteForecast covers exactly this window).
  • No iPad-specific UI beyond what SwiftUI gives for free (this is iPhone-first).

Constraints

  • iOS 17+ (WeatherKit’s Swift API, App Intents 2.0, Live Activities).
  • US-only by default for alerts (WeatherKit alerts have limited international coverage; document this in the README).
  • Apple Developer Program membership required (WeatherKit needs a paid account and a WeatherKit capability in the App ID).

Out of scope (explicitly)

These will be tempting to add — say no:

  • Push notifications via APNs (use local notifications keyed to the saved location’s timeline; APNs requires a server and is a different capstone)
  • Marketing site (your GitHub README is enough)
  • iCloud key-value store (CloudKit private DB is enough; do not add a second sync layer)
  • A backend service of any kind — WeatherKit + CloudKit cover everything

Next: Architecture