Repository navigation
SalahKit 0.3.0
SalahKit 0.3.0 adds examples, documentation and the project's governance. The public API is unchanged since 0.2.0.
- Examples/MenuBar: a macOS menu-bar app that keeps running, with prayer alerts and a desktop widget whose Stop button stops the app's tone. It covers the cross-process stop round trip that 0.2.0 left pending; a real tap on the widget is still to observe.
- MosqueBoard on Apple TV, built from the iPad app's shared code.
- The article "Lessons from Salah", on acting on the Darwin signal, gating widget reloads and keeping the language's digits.
- Governance: an RFC process in CONTRIBUTING.md with a GitHub Discussion for each RFC (#6–#9), CODEOWNERS, and
.spi.ymlfor the Swift Package Index. - Fixes: SalahUI keeps the hour's leading zero in 24-hour locales (#11); the README's widget helper and the stop signal's declaration compile in a module that defaults to the main actor; the parity study names the right adhan-swift version (#15).
The full list is in CHANGELOG.md.
Proven
- The cross-process stop round trip (pending in 0.2.0, now covered).
Examples/MenuBar's widget Stop button runsStopPlaybackIntent, which clears the sharedNowPlayingvalue and posts aDarwinSignal.MenuBarStopHarness, a separate process sandboxed and signed like the widget extension with the same App Group, ran the intent's ownperform()against the running, sandboxed app on macOS 27 (team-signed): the app received the signal, stopped the tone, and republished; the stored value was gone and the widget's timeline, built by the extension's code from the stored values, no longer showed the Stop button. With only the signal posted (the stored value still saying "playing"), the app stopped anyway and its republish cleared the value. The same tests pass unsigned on CI. - MenuBar's display, alerts, sleep and clock changes. The menu-bar title is static text refreshed at the dates of a
.stepsrefresh plan: a journey watched the real status item turn to "Asr started 0 seconds ago" at Asr and "Asr started 1 minute ago" a minute later.InProcessAlertEnginefollows the uncappedAlertScheduleandNotificationSchedulerinstalls the budgetedNotificationPlan; unit tests show a reminder the plan left out still comes due, gets a banner throughdeliverand plays the tone, and two alerts due together play the one the engine's default precedence picks. Wake and clock-change notifications posted to injected notification centers catch alerts up within their grace and replan, a time-zone change replans, and a caught-up alert whose request is still pending gets its banner after the replan (the app delivers after the replan'sapply, which the alerts article now advises); in the running app, a simulated three-minute sleep through Asr caught its alert up after the wake, and a ten-minute clock change skipped it and redrew the title. - MosqueBoard on tvOS, built from the iPad app's shared code and linking only SalahCore: unit tests and journeys (a normal day, Jumu'ah, the expired timetable, Isha after midnight, a partial row, Arabic, and the tallest board, from Isha to its iqama, in English and Arabic) passed on an Apple TV 4K (3rd generation) simulator with tvOS 27; the iPad journeys still pass.
- SalahUI's times are the locale's own short time format (#11): content tests pin French, Turkish, Indonesian and British English ("04:11"), on macOS and Linux; the snapshots (English and Arabic) are unchanged.
- Documentation: the article "Lessons from Salah", whose code runs in the package's tests; every article and README snippet those tests mirror also builds in a module that defaults to the main actor, including from a widget provider that isn't on the main actor; the strict DocC build of all six modules; the site at https://salah-kit.github.io/SalahKit/; the parity study's adhan-swift version corrected (#15).
- CI on the tagged commit (run 38535019816): every job green on GitHub's hosted runners (Linux with Swift 6.2 and the latest Swift, macOS with Xcode 26, both default-isolation settings), including the new MenuBar and MosqueBoard tvOS jobs.
Pending
These need a person, a device or time. Each issue has the steps:
- A real tap on MenuBar's desktop widget Stop button: the harness runs the intent's code in its own process, not inside the widget extension WidgetKit launches (#29).
- MenuBar across real Mac sleep, wake and a clock change, with its banners; the round-trip tests make the app post the notifications to itself (#28).
- MosqueBoard on a real Apple TV connected to a TV: overscan and the screen saver (#27).
- Native-speaker review of the examples' Arabic: MenuBar's 51 strings are machine-drafted and marked
needs_review(#31; the other examples: #32, #33, #34, #35). - Carried over from 0.2.0: the seven-day iPhone widget soak (#23); WatchComplication on a real Apple Watch (#25); timeline cost on the oldest supported iPhone (#24); closed-app alert delivery on a real iPhone (#22); in-process reminders across real Mac sleep and wake (#28); and outside API reviews of RFC 0003 and RFC 0004, now discussions #8 and #9 (#43).
Settled since this release. These were pending when 0.3.0 was released:
- Submitting SalahKit to the Swift Package Index (
.spi.ymlwas ready): listed on 2026-10-14. - Carried over from 0.2.0, a decision on the contrast of CalculatedPhone's banner border and the plain styles' secondary text: made in 0.4.0 (see its Known limitations).
Known limitations
- With "Play the app's tone" on (the default), MenuBar's notifications carry no sound of their own, so one that arrives while the app isn't running is silent; with it off, they use the system's sound and the app plays nothing.
- A
.staticTextcountdown shows the time left at its entry's date, rounded down: until the next step it can overstate the time left by up to one step. - The macOS XCUITest runner is sandboxed and can't start another sandboxed process, so the round trip runs from a hostless test bundle rather than XCUITest.
- CI builds and tests MenuBar unsigned, without the sandbox and App Group; the signed, sandboxed run is local.
- On the iOS 27.0 simulator, notification requests added right after the first permission are rejected until the simulator restarts (from 0.2.0).
- Requests from Salah's move onto SalahKit that add API stay open for an RFC 0004 amendment: rows for the kinds a partial day is missing (#12), a count-up and the next event in
NextPrayerView(#13), and midnight entries fromPrayerTimelineBuilder(#14).