Appendix I: Claudes Outdoor Utility (Shop Manual)

Status: Live. GPL v3. Public repo at github.com/fluhartyml/Claudes-Outdoor-Utility. Build-Along chapter: Part VII Build-Along 05. Claudes Outdoor Utility is a weather-stamped photo journal for iPhone and iPad. One tap captures a photo, the current weather, the user's location, a title, and a free-text note — one entry, frozen at that moment. Past entries browse chronologically or pinned on a map. Apple Photos remembers GPS but not weather; this app fills that gap.

What it is

A weather + location journal. Each entry is one moment in time: a photo, a title, the weather at the time of capture, the lat/lng coordinates, an optional free-text note, and a timestamp. The Home tab shows a map with a pin for every entry. The Log tab shows a reverse-chronological list. The New Entry tab is the capture flow. The Under the Hood tab surfaces the source for curious readers.

v1.0 ships the journal + map. v2.0 adds a RainViewer radar overlay on top of the existing map — same data model, new visualization layer.

Architecture overview

SwiftUI + SwiftData app with five Apple framework dependencies (no third-party). 20 Swift files.

The data model

@Model
final class OutsideLog {
    var id: UUID
    var timestamp: Date
    var title: String
    var lat: Double
    var lng: Double
    var weatherSummary: String
    var weatherTemp: Double
    var weatherSymbol: String
    var photoData: Data
    var note: String

    init(/* ... */) { /* ... */ }
}

Weather is stored as a flat triple (summary + temp + SF Symbol name) rather than a nested struct because the frozen reading doesn't need to be re-queryable — the entry is a moment, not a live data source.

The photo + location privacy rule (locked)

Per project memory feedback_photo_location_privacy.md, when an app handles photos plus location, it stores the location in its own data model and never modifies the photo's EXIF. The iOS camera-location setting is the user's single authority over whether their photos carry location data; an app that writes its own location into a photo's EXIF overrides that authority without the user's awareness.

Outdoor Utility follows this rule strictly: OutsideLog.photoData holds the raw bytes the user picked / captured, and OutsideLog.lat + OutsideLog.lng hold the location the app reads from CoreLocation. The photo's own EXIF is not touched. If the user has iOS camera location turned off, the photo's EXIF stays clean; the app's location data is its own.

WeatherKit fetch + attribution

WeatherFetcher calls WeatherKit's current-conditions API at log time, extracts the summary string, temperature, and SF Symbol name, and writes them into the new OutsideLog entry. The reading freezes — the entry stores what the weather was at capture time, not what it is right now.

Apple requires attribution for WeatherKit data. WeatherAttributionRow renders that attribution as part of any view that displays weather data — the Entry Detail view, the share-builder map snapshot, the New Entry preview. Per project memory feedback_weatherkit_attribution_varies.md, App Review's verdict on attribution placement is reviewer-variable; an attribution that passes one reviewer may get flagged by another. The app's defensive posture is to show attribution prominently everywhere weather appears, not just once.

Capture flow

  1. User opens the New Entry tab.
  2. The user types a title (required — the rule below).
  3. The user picks a photo source: camera (CameraPicker) or library (PhotosPicker).
  4. The app reads the user's current location via LocationManager. Permission prompt fires on first use only.
  5. The app calls WeatherFetcher for current conditions at those coordinates.
  6. The user adds an optional free-text note.
  7. On Save, a new OutsideLog entry is inserted into the SwiftData store.

Locked design rules

Sharing

EntryShareBuilder assembles a composite share artifact: the photo on top, the weather card below, a map snapshot from MapSnapshotter at the bottom. The result is a single rendered image the user can share through any normal share target (Messages, Mail, AirDrop, Photos). ActivityShareSheet wraps UIActivityViewController for the presentation.

Build + deployment

v2.0 roadmap

v2.0 adds the RainViewer radar overlay to the Home tab map. Same data model, new visualization. Other v2.x candidates:

Known gotchas

Sources