- App sources live under
IngrediCheck/; SwiftUI screens sit inViews/, shared helpers inUtilities/, and observable state inStore/(e.g.,AuthController.swift,NetworkState.swift). - Network access is handled by
WebService.swiftandSupabaseRequestBuilder.swift; keep API DTOs inDTO.swiftto share models across features. - Assets and localized imagery are managed inside
Assets.xcassets; update catalog groups rather than adding ad-hoc bundles. - Configuration constants (Supabase endpoints, analytics keys) are defined in
Config.swift; use environment-specific overrides before shipping secrets.
xed IngrediCheck.xcodeproj— open the Xcode project.xcodebuild build -project IngrediCheck.xcodeproj -scheme IngrediCheck -destination 'platform=iOS Simulator,name=iPhone 15'— CI-friendly build to catch compile issues.xcodebuild test -project IngrediCheck.xcodeproj -scheme IngrediCheck -destination 'platform=iOS Simulator,name=iPhone 15'— execute unit/UI tests once targets exist.
We run two MCP servers for iOS development: XcodeBuildMCP (Sentry) and Apple Xcode MCP.
Prerequisite for Apple Xcode MCP: Requires Xcode 26.3+ and macOS Tahoe+. Xcode must be running with the current project open. Run xed IngrediCheck.xcodeproj to open it before using any mcp__xcode__* tools. If you had to open Xcode yourself (it wasn't already running), the xcode MCP server will likely show as disconnected — ask the user to run /mcp and reconnect the xcode server before proceeding.
| Capability | XcodeBuildMCP | Apple Xcode MCP | Prefer |
|---|---|---|---|
| Build project | build_sim, build_run_sim |
BuildProject |
XcodeBuildMCP — session defaults reduce tokens, no Xcode IDE required |
| Run tests | test_sim |
RunAllTests, RunSomeTests |
XcodeBuildMCP — integrates with simulator management and log capture |
| Get build errors | build_sim (returns errors) |
XcodeListNavigatorIssues |
XcodeBuildMCP for build errors; Apple MCP for live Xcode diagnostics |
| List tests | test_sim --list |
GetTestList |
Either — equivalent |
RenderPreview— SwiftUI preview screenshots (visual UI verification)DocumentationSearch— semantic search across Apple docs + WWDC transcriptsExecuteSnippet— Swift REPL for quick experiments without full buildsXcodeListNavigatorIssues— live Xcode Issue Navigator diagnostics
- Simulator management (
list_sims,boot_sim,open_sim) - App lifecycle (
install_app_sim,launch_app_sim,stop_app_sim) - Log capture (
start_sim_log_cap,stop_sim_log_cap) - Screenshots and video (
screenshot,snapshot_ui,record_sim_video) - UI automation (taps, swipes, gestures, text input)
- LLDB debugging (attach, breakpoints, stack inspection)
- Device deployment (build, install, launch on physical devices)
- Project scaffolding and discovery
- Follow Swift 5.9 defaults: four-space indentation, 120-char line guidance, and use trailing commas for multiline literals.
- Types use
UpperCamelCase, methods/properties uselowerCamelCase, and SwiftUI view files match the primary view name (e.g.,DisclaimerView.swift). - Group extensions and previews with
// MARK:comments for discoverability; prefer protocol-oriented patterns for shared behavior. - Run Xcode's “Re-Indent” and enable
swiftformatorSwiftLintlocally; do not commit warnings.
- Create
IngrediCheckTestsandIngrediCheckUITeststargets for new coverage; mirror production folder names to keep scopes clear. - Use
XCTestnamingtest<Scenario>_<ExpectedBehavior>and include async tests for Supabase/network flows. - Mock network dependencies via
WebServiceprotocols to avoid live Supabase hits; capture fixtures underTests/Fixtures. - Aim for coverage of state stores (auth, onboarding, dietary preferences) and UI flows gating onboarding/consent screens.
- Prefer conventional titles with a leading area tag (
Feature:,Fix:,Chore:) and optional issue references, mirroring recent history (Feature: Switch to SSE API (#8)). - Keep commits scoped to a single concern and include rationale in the body when touching config, analytics, or secrets.
- PRs should summarize functional changes, list test evidence (
xcodebuild build,xcodebuild test), link Supabase/issue tracker tasks, and add screenshots for UI updates. - Request at least one review, resolve Xcode warnings before merging, and ensure build settings remain in sync.
NEVER commit with useLocalBackend = true in Config.swift
Before committing:
- Check Config.swift: Verify
useLocalBackendis set tofalseor uses#if DEBUGguard - Verify production URLs: Ensure the app will connect to production endpoints
- Test production build: Build with Release configuration to ensure production URLs are used
The useLocalBackend flag is protected by #if DEBUG in code, but always double-check before committing. Local endpoints (192.168.x.x) should NEVER be in committed code.
We track work in Beads instead of Markdown. Run `bd quickstart` to see how.
When ending a work session, you MUST complete ALL steps below. Work is NOT complete until git push succeeds.
MANDATORY WORKFLOW:
- File issues for remaining work - Create issues for anything that needs follow-up
- Run quality gates (if code changed) - Tests, linters, builds
- Update issue status - Close finished work, update in-progress items
- PUSH TO REMOTE - This is MANDATORY:
git pull --rebase bd sync git push git status # MUST show "up to date with origin" - Clean up - Clear stashes, prune remote branches
- Verify - All changes committed AND pushed
- Hand off - Provide context for next session
CRITICAL RULES:
- Work is NOT complete until
git pushsucceeds - NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds