iOS Engineering Handbook
This is the canonical iOS/macOS engineering document for sideBar.- Source of truth for Apple-platform setup, architecture, and operations.
- Applies to:
ios/sideBarapp target, extensions, shared framework, and Apple test targets. - Last reviewed:
2026-02-10.
Scope and Project Layout
- Project root:
ios/sideBar - Main app target:
ios/sideBar/sideBar - Shared framework:
ios/sideBar/sideBarShared - Share extension:
ios/sideBar/ShareExtension - Widgets extension:
ios/sideBar/sideBarWidgets - Safari extensions:
ios/sideBar/sideBar Safari Extension* - Tests:
ios/sideBar/sideBarTests,ios/sideBar/sideBarUITests
Platform and Tooling Requirements
- Xcode with iOS/macOS 26 SDK support.
- Apple simulator runtimes used in CI:
iPad Pro 13-inch (M5)(iPadOS 26.0)iPhone 17 Pro(iOS 26.0)macOS(arm64, macOS 26)
- Swift toolchain version from project settings:
Swift 5.
Local Setup
- Copy
ios/sideBar/Config/SideBar.local.xcconfig.exampletoios/sideBar/Config/SideBar.local.xcconfig. - Fill in all required runtime keys.
- Open
ios/sideBar/sideBar.xcodeprojin Xcode. - Ensure Debug base configuration points to
Config/SideBar.xcconfig. - Build and run the
sideBarscheme.
Runtime Configuration (Required Keys)
Runtime values come from.xcconfig and are exposed via Info.plist build settings.
API_BASE_URLSUPABASE_URLSUPABASE_ANON_KEYAPP_GROUP_IDKEYCHAIN_ACCESS_GROUPKEYCHAIN_SERVICEASSOCIATED_DOMAINS(for examplewebcredentials:app.trysidebar.ai)R2_ENDPOINTR2_BUCKETR2_FAVICON_BUCKETR2_FAVICON_PUBLIC_BASE_URL
- Non-production runtime paths fail fast when required configuration is missing or invalid.
- Non-production builds do not silently fall back to production API endpoints.
Architecture Summary
Primary pattern is MVVM with an explicit Store layer:Views: SwiftUI rendering and user interaction.ViewModels:@MainActorstate orchestration and user intent handling.Stores: cache-first data coordination, realtime mapping, and persistence integration.Services: network/auth/cache/realtime/upload/persistence infrastructure.
- UI triggers view-model action.
- View model delegates to store/service APIs.
- Store updates
@Publishedstate from cache/network/realtime. - SwiftUI reacts to published state changes.
Architecture Boundaries (CI-Enforced)
Layering constraints are enforced byscripts/check_ios_architecture_boundaries.py:
Servicescannot depend onStores,ViewModels, orViews.Storescannot depend onViewModelsorViews.ViewModelscannot depend onViews.
Testing and Quality Gates
Local validation commands:scripts/test-ios.sh defaults to serial execution when the lane includes sideBarUITests (for simulator stability), unless IOS_PARALLEL_TESTING_ENABLED is explicitly set.
CI workflow (.github/workflows/ios-ci.yml):
- Runs on two self-hosted runners on the developer machine:
iosrunner: iPad and iPhone simulator test lanes (sequential).macrunner: macOS native test lane, quality checks, and hard gates.
- Triggers: push to
devbranch only (path-filtered toios/**and CI scripts), plus manualworkflow_dispatch. - Quality job (parallel with test matrix):
- SwiftLint
- iOS doc-comment coverage check
- Architecture boundary check
- Test matrix (parallel with quality job):
- iPad lane: UI tests only, coverage disabled.
- iPhone lane: all tests except UI tests, coverage enabled.
- macOS lane: unit tests only, coverage disabled.
- Hard gates (runs after both quality and test matrix complete):
- Per-target coverage thresholds and baseline-drop enforcement via
scripts/check_ios_quality_gates.py. - First-party iOS target warning gate via
scripts/check_ios_quality_gates.pywarning policy. - Uses iPhone lane xcresult only.
- Per-target coverage thresholds and baseline-drop enforcement via
.git/hooks/pre-push):
- Blocks pushes to
mainunlessscripts/test-ios.shpasses locally. - Blocks pushes to
mainunlessscripts/check-main-linear-history.shpasses:- pushed
maintip must match localdevtip - push range may not include merge commits
- non-fast-forward updates to
mainare rejected
- pushed
- Pushes to
devand other branches are unblocked. - Guards against broken builds reaching Xcode Cloud.
pre-commitpush-stage hookios-warning-gaterunsscripts/check-ios-warning-gate.shfor iOS/script changes and fails on scoped warnings.
main linear by rebasing dev on origin/main, fast-forwarding main, then publishing the rebased dev branch with --force-with-lease.
Self-Hosted Runner Setup
Two GitHub Actions runners run locally on the developer machine:ios-runner(label:ios, installed at~/Coding/actions-runner-ios): handles iPad and iPhone simulator lanes.mac-runner(label:mac, installed at~/Coding/actions-runner-mac): handles macOS lane, quality checks, and hard gates.
dev.
Xcode Cloud Notes
- Script:
ios/sideBar/ci_scripts/ci_post_clone.sh - It generates
SideBar.local.xcconfigfrom environment variables. - Missing required values fail the build early.
- Xcode Cloud handles
mainbranch builds for distribution.
Extension Reliability Expectations
- Share, widget, and Safari extension families should each have deterministic XCTest coverage.
- Keep extension-specific contract tests focused on:
- message/deeplink shape validation
- auth/config edge cases
- retry/recovery behavior
Documentation Map
Use this handbook as primary reference.- Quick project orientation:
ios/README.md - Environment key detail:
ios/ENVIRONMENT.md - Legacy architecture page (deprecated pointer):
docs/IOS_ARCHITECTURE.md - Active/historical iOS implementation plans:
docs/plans/