A single-purpose daily-focus iOS app.
OneThingTodayKit/ — a local Swift package, Clean-Architecture style:
- OneThingTodayDomain — entities, use cases, repository protocols. Pure Swift, no Apple frameworks. Phase 0 + Phase 1, done and tested.
- OneThingTodayData — SwiftData persistence (Phase 2), AlarmKit scheduling (Phase 3), the ActivityKit-backed Live Activity + relay engine (Phase 4), and the on-device Foundation Models AI service (Phase 5).
OneThingToday/ — the app target: onboarding, and the Today / Weekly
Digest / Settings screens, each with its own @Observable view model,
wired up by AppContainer (the composition root). OneThingTodayWidget/
— the widget extension target: the Live Activity's Lock Screen card and
Dynamic Island (compact/minimal/expanded). Both are generated from
project.yml via xcodegen generate.
Captured on a real iOS 26.5 simulator run — including a genuine on-device Foundation Models response in the Weekly Digest shot below, not a mock.
| Onboarding | Times | Permission | |
|---|---|---|---|
![]() |
![]() |
![]() |
|
| Today (empty) | Today (active task) | Weekly Digest | Settings |
![]() |
![]() |
![]() |
![]() |
Whole app + widget extension, in Xcode:
xcodegen generate # regenerate OneThingToday.xcodeproj after editing project.yml
open OneThingToday.xcodeproj
Build/run the OneThingToday scheme on an iOS 26+ simulator or device.
Domain-only tests (no device needed, but run via Xcode/xcodebuild against
an iOS Simulator destination — OneThingTodayData now imports AlarmKit +
ActivityKit, so the package is iOS-only and a plain swift test on macOS
will fail on Foundation availability, not a real bug):
cd OneThingTodayKit
xcodebuild test -scheme OneThingTodayKit-Package -destination 'platform=iOS Simulator,name=iPhone 17 Pro'
Not a code artifact — filled in by hand under App Store Connect → your app → App Privacy when the app record is created. Every category is Data Not Collected, because there's no account, no analytics SDK, no network calls, and no server anywhere in the stack: the task text, reflections, and schedule live only in the on-device SwiftData store, and the on-device Foundation Models calls (Sharpen, weekly summary) never leave the phone.
| Category | Answer |
|---|---|
| Contact Info | Not Collected |
| Health & Fitness | Not Collected |
| Financial Info | Not Collected |
| Location | Not Collected |
| Sensitive Info | Not Collected |
| Contacts | Not Collected |
| User Content | Not Collected |
| Browsing History | Not Collected |
| Search History | Not Collected |
| Identifiers | Not Collected |
| Purchases | Not Collected |
| Usage Data | Not Collected |
| Diagnostics | Not Collected |
| Other Data | Not Collected |
Phase 7 (polish & App Store prep) is done. Landed this pass: a real app icon
(OneThingToday/Assets.xcassets/AppIcon.appiconset), a distinct "no history
yet" empty state on the Weekly Digest screen instead of a wasted on-device
model call on a brand-new user's first day, and a fix for a real onboarding
trap — declining the AlarmKit permission used to leave a user stuck on the
permission screen forever (AlarmKit denial can only be reversed from the iOS
Settings app, not by re-prompting), so onboarding now offers "Continue
Without Reminders"; Settings shows the same denied state with a direct "Open
Settings" button. A second real bug turned up live-testing the walkthrough
for the screenshots below: Settings always claimed "alarms aren't scheduled
yet" on open even right after onboarding scheduled them, since it never read
back any persisted state — fixed with a small UserDefaults flag both
onboarding and Settings write on success. App Store screenshots (below) are
done, and the Privacy Nutrition Label answers are above, ready to paste into
App Store Connect. Monetization (the plan's optional StoreKit gate for the
digest) is deliberately skipped for v1.
Everything through Phase 7 (domain layer, persistence, AlarmKit scheduling,
the Live Activity relay engine, on-device Foundation Models, all four app
screens, the icon, and the permission/empty states) is built and, as of this
pass, actually verified with xcodebuild against a real iOS 26.5 simulator
— both the app+widget build and the full OneThingTodayKit domain test
suite (16 tests) pass.
Next: Phase 8 (QA & submission) — this is the one phase that needs a physical iPhone rather than the simulator, since it's testing real AlarmKit
- Live Activity behavior over actual elapsed hours, not compressed/simulated time:
- Three or more full real-device days with different morning/evening time combinations
- A short TestFlight beta, watching specifically for "the Lock Screen went blank" reports
- App Review notes explaining the AlarmKit usage plainly — real, user-requested daily alerts, not background scheduling in disguise
- Exit criterion: submitted, with a written note of what to change for v1.1






