Repository navigation
Requires realm-swift 20.x
This is the reason for the major bump. The Swift API is additive — no public symbol was removed
or changed signature — but SwiftPM cannot resolve 2.0.0 alongside a host app pinning realm-swift 10.x.
1.x no longer builds on current toolchains. realm-core's PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT macro
specializes std::is_pod, which current libc++ rejects outright:
'is_pod' cannot be specialized: Users are not allowed to specialize this standard library entity
realm-core 20.1.5 neuters that macro upstream. Bumping core alone was impossible — realm-swift pins it
with exact: — and build flags can't reach a SwiftPM package target. Upgrading was the only fix.
Your Realm data carries over. The bundled quran.realm is unchanged in 2.0.0 — byte-identical to
the one 1.x shipped, at Realm file format 23. It is copied into Application Support only when absent,
so an app updating from 1.x keeps the copy it already made. realm-swift 20 opens that file directly.
2.0.0 cannot be reopened by a 1.x build. Worth one pass against real 1.x data before shipping.
See Migrating to 2.0.0 for the full path.
Unified Quran playback
Playback previously lived in several QuranPlayerViewModel instances that didn't know about each
other. QuranPlayerCoordinator is now the single source of truth for what is playing.
- Players self-register when playback starts. Registration used to depend on a view remembering to
do it, so the coordinator was stale or nil while another player was audibly playing. Hosts should
now delete any manualregisterActivePlayercalls — see the migration guide. - Playback is exclusive. Starting a second player pauses the first. Two players could previously
stream at once. - The lock screen survives a player swap. Remote commands late-bind to the active player at
invocation time. Previously the first player to ever play owned the lock screen for the process
lifetime, and once it deallocated the controls became dead no-ops nothing could reclaim. QuranPlayerCoordinator.nowPlayingpublishes the recited chapter and verse for hosts to follow.
verseNumber == 0is the opening basmala.
Behavior change: MushafView follows recitation
MushafView with no highlight of its own now highlights the recited verse and turns to its page
as audio plays — the reported defect. Hosts passing a highlightedVerse binding or a static verse
are unaffected: your value wins and playback never overrides it.
Also fixed
SurahVerseCounts— dedups two copies that had drifted apart and adds a bounds check; the old
verseCounts[chapterNumber - 1]was a crash waiting for an out-of-range surah.- Reciter catalog — all 18 entries regenerated from the timing JSON. Folder URLs were 3/18 correct.
Drift tests now hold them to the JSON. TafseerService.progressValue— no longer reports a full bar for.idleand.failed.MushafViewpage-follow — scrolls to the highlighted verse's page when a host-driven binding
changes.MushafViewdead player removed — it owned a private player nothing could start.
Eye tracking is experimental
Now documented as such. Its gaze estimation and geometry maths are incomplete — the fallback
estimator's gaze does not advance down the page over time, gaze-to-verse mapping does not resolve in
landscape or after an orientation change, and line tracking does not recover after a rotation. The
tests covering these are marked as known issues. The feature is opt-in and self-contained; the Mushaf
reader and audio playback are unaffected if you never enable it. Not recommended for production.
Known issue
Deallocating the active player fires no objectWillChange, so nowPlaying does not self-invalidate
and a highlight can go stale. Normal teardown notifies; the gap is the macOS force-quit path.