Remove watchOS simulator targets, deploy functions, boot helpers, icon generation, preflight checks, and test runner code from all scripts. Update README, copilot instructions, and PlatformUi.swift. Wear OS (Android) code is kept intact. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
IF Tracker
IF Tracker is a Kotlin Multiplatform Mobile (KMM) app for intermittent fasting tracking on Android (Jetpack Compose) and iOS (SwiftUI), with a companion app for Wear OS.
All user data is stored locally on-device (SQLite via SQLDelight). There is no backend.
Table of Contents
- Key Features
- Build & Run
- Testing
- Security Portfolio
- Development Guidelines
- Lessons Learned
- Specs, Scripts, Evidence
- License
Key Features
Tracking
- Start/end fasts, notes
- Edit history, pagination for large histories
- Goals, streaks, analytics summaries
Import/Export
- JSON backup export/import (with metadata)
- Duplicate detection on restore/import (idempotent re-import)
- Zero app import (JSON + ZIP)
Sync (local-only)
- Local peer sync over LAN (NSD/Bonjour) using one-time codes
Notifications & Widgets
- Daily + streak reminders and fast completion alarms
- Android AppWidget + iOS WidgetKit widgets
Build & Run
Shared module
./gradlew :shared:build
Android app
./gradlew :androidApp:assembleDebug
Wear OS app
./gradlew :wearApp:assembleDebug
iOS
- Build/run from Xcode:
iosApp/iosApp.xcodeproj
Deploy helpers
- Device deployment script: scripts/deploy_all_devices.sh
- Emulator deployment script: scripts/deploy_all_emulators.sh
Testing
Single entry point
Evidence requirements
- Never claim UI tests passed without real emulator/simulator execution.
- Store outputs under
test-logs/with:- device/emulator identifier
- pass/fail counts
- (iOS)
.xcresultartifacts when applicable
Preflight
- Android/Wear:
adb devices - iOS:
xcrun simctl list devices | grep Booted
Security Portfolio
This project is local-only (no server, no accounts). Security focus is on local persistence, import/sync hardening, and safe logging.
Threat Model
- Malicious or malformed import payloads (JSON/ZIP)
- LAN adversary attempting sync-code guessing
- Accidental data duplication on restore/re-import
Implemented Controls
Data at rest
- SQLite stored locally with OS-level device encryption.
Local sync security
- Encrypted payloads (AES-256-GCM)
- Key derivation via PBKDF2-SHA256
- One-time sync codes with rate limiting
- Timing-safe comparisons for code checks
Import/export validation
- Size limits and schema validation for JSON/ZIP
- Duplicate detection using composite key
(date, startTime, endTime) - Sanitized user-facing error messages
Logging
- Avoid logging secrets / sync codes / sensitive payload fragments
Development Guidelines
Architecture
- MVVM + Repository pattern
Result<T>for error handling- Validate all user inputs before persistence
Kotlin/Native to Swift Interop (Quick Reference)
| Pattern | Notes |
|---|---|
Kotlin suspend |
Becomes completion handler in Swift (not async/await) |
Kotlin Result<T> |
Opaque in Swift; extract via casting (as?) or bridge helpers |
| Kotlin class names | Can appear with _ suffix in Swift (verify generated headers) |
| SQLDelight on iOS | Ensure -lsqlite3 is linked |
Import/Restore Duplicate Handling
Duplicate skipping uses a composite key derived from:
- session date
- start time
- end time
This keeps imports idempotent (re-importing the same file should not endlessly duplicate history).
Lessons Learned
-
Large README changes should replace full intended ranges (avoid leaving duplicate sections).
-
Test status must be backed by emulator/simulator evidence in
test-logs/.
Specs, Scripts, Evidence
- Specs and work plans: specs/
- Emulator test coverage spec: specs/002-emulator-test-coverage/spec.md
- Wear OS redesign spec: specs/003-wearos-post-mvp-redesign/spec.md
- Test runner: scripts/run-emulator-tests.sh
- Evidence artifacts:
test-logs/
License
Proprietary - All rights reserved.