A lightweight SwiftUI app to track your Dates of Interest with a clean list, colorful countdown pills, and persistence. Built using CLEAN architecture with MVVM + Coordinator. Fully offline; no external APIs.
- Two tabs: Upcoming (Today + future, ascending) and Past (past, descending)
- Each row shows an SF Symbol, title, localized date, and a countdown pill
- Countdown pill formats as:
- future: “X”
- past: “- X”
- today: “Today”
- Persistence via
UserDefaults(MVP) - Accessibility: contrast-safe pills; Dynamic Type support
- Localization: English and Portuguese (Brazil)
- CLEAN layering:
UI → Presentation (MVVM) → UseCases → Domain → Data - Coordinator owns navigation: see
Countdown/Presentation/Coordinators/AppCoordinator.swift - Key folders:
Countdown/Domain— entities and repository protocolsCountdown/UseCases— business rules (partitioning, add/update)Countdown/Data—UserDefaultsrepository + mappersCountdown/Presentation— view models, formatters, colors, coordinatorsCountdown/UI— screens and components
- Xcode 15.4+
- iOS 17.5 Simulator (recommended) or device
- Open
Countdown.xcodeproj. - Select the
Countdownscheme. - Build (Cmd+B) and Run (Cmd+R).
- Run tests (Cmd+U) or via scripts:
scripts/ci/build-and-test.shscripts/ci/check-coverage.sh(coverage gate: 80%)
- UI tests live under
CountdownUITests/. - Performance test:
PerformanceScrollingTests(100 items scroll).
Add to Scheme → Run → Arguments → Arguments Passed On Launch:
UITEST_CLEAR_DATA— clears stored itemsUITEST_PRELOAD_DATA— preload 3 sample itemsUITEST_PRELOAD_100— preload 100 items (perf)UITEST_AUTO_DATE— Add/Edit treats date as picked
- String Catalog:
Countdown/Resources/Localizable.xcstrings - Supported:
en,pt-BR
- Dynamic Type-ready text styles
- Pill foreground color adapts for contrast; past entries use system primary on gray background
- GitHub Actions workflow at
.github/workflows/ios-ci.yml- Builds and tests with coverage
- Enforces coverage via
scripts/ci/check-coverage.sh - Uploads
TestResults.xcresultartifact
- Follow Swift API Design Guidelines and the existing code style.
- Keep responsibilities within the appropriate CLEAN layer.
- Add unit tests (and UI tests, if applicable) for new features.
This project is licensed under the terms of the LICENSE file.