Overview
- What It Is: A native SwiftUI espresso journal for serious home espresso enthusiasts, built to log shot inputs quickly, preserve brew context, and turn daily pulls into useful analytics.
- Goal: Make home espresso dialing-in easier to repeat and improve by tracking dose, yield, time, grind, beans, grinder, notes, weather context, shot scores, and extraction trends in one polished iOS app.
Key Achievements & Features
- Native iOS Product Architecture
- Built as an Xcode iOS project with the primary
EspressoLyticsscheme plus a dedicatedEspressoLyticsScreenshotsscheme for App Store media automation. - Uses SwiftUI for the product surface, SwiftData for local persistence, and a structured feature layout across Home, History, Settings, Services, Support, Models, Components, and Theme modules.
- Targets modern iOS with bundle ID
com.zachnovak.EspressoLytics, local version1.0, and build4recorded in the Xcode project and release notes.
- Built as an Xcode iOS project with the primary
- Espresso Logging Workflow
- Logs dose, yield, extraction time, grind size, bean, grinder, tasting notes, and brew timestamp through a fast Daily Log flow designed for repeated use while dialing in.
- Uses reusable defaults for bean, grinder, and grind size so routine shots can be entered quickly without turning the app into a spreadsheet.
- Includes a separate Dial-in mode for grind-tuning attempts so experimental shots can be compared without skewing the regular shot history.
- Weather-Aware Brew Context
- Integrates WeatherKit and CoreLocation to attach local temperature and humidity context to espresso entries.
- Supports refresh and permission-aware status handling so weather context degrades cleanly when location or WeatherKit access is unavailable.
- Includes historical weather lookup support so backfilled brew entries can still capture nearby environmental conditions when possible.
- Analytics and Shot History
- Models each shot with SwiftData fields for brew ratio, calculated extraction score, temperature, humidity, normalized bean identifiers, grind size, dial-in session data, and timestamps.
- Builds a History surface with extraction trend charts, brew-ratio analysis, quality snapshot metrics, bean lookup, filters, pagination, and a tabular recent-shot view.
- Uses Swift Charts and a dedicated heatmap chart component to make the logged data useful instead of just stored.
- Polished Coffee-Focused UX
- Uses a custom espresso-themed visual system with glass-style cards, warm accent colors, rounded typography, and reusable UI components.
- Adds popup feedback, confirmation flows, settings preferences, unit display options, and clear-history maintenance actions for daily usability.
- Keeps the app intentionally focused on the espresso ritual rather than generic habit tracking.
- Release and Portfolio Readiness
- Includes Fastlane metadata, screenshot, validation, and upload lanes for App Store Connect workflows.
- Local release docs record version
1.0, build4, submitted to App Review on April 30, 2026, with App Store Connect showingWAITING_FOR_REVIEWat that time. - Maintains a dependency security posture through pinned Swift package versions, Dependabot configuration, a dependency security audit workflow, and documented audit notes.
Technologies & Skills Demonstrated
- SwiftUI
- SwiftData
- Swift Charts
- WeatherKit
- CoreLocation
- Xcode
- Fastlane
- StoreKit/App Store Connect Release Workflow
- PopupView
- ExyteGrid
- ConfettiSwiftUI
- SwiftUI Introspect
- GitHub Actions
- Dependabot
Big-Picture Vision
- Better Home Espresso Feedback: The product turns a messy daily ritual into a repeatable log, so beans, grinders, weather, and extraction behavior can be compared over time.
- Small App, Real Product Discipline: EspressoLytics is intentionally narrow, but it still carries product details that matter: persistence, analytics, UI polish, release docs, screenshot automation, metadata, and dependency review.
- Practical Personal Software: The app reflects the kind of software I like building: focused tools that solve a real workflow, respect the user's time, and make the underlying data easier to act on.