Release Note · Swift Toolkit Version 3.5.0

We are happy to announce the release of the 3.5.0 version of the Swift toolkit. This new version of comes with improvements to EPUB layout and legibility, as well as new utilities for text-to-speech (TTS) and more flexible integrations for LCP.

Release Note · Swift Toolkit Version 3.5.0

Browse the full release on GitHub

More resilient, predictable layouts in the EPUB navigator


The first element that was added to the toolkit is the possibility to customize content and safe-area insets used by the navigator. The goal is to ensure that apps can define stable content insets to prevent layout shifts when system UI appears or disappears.

By default, the navigator use the window's safeAreaInsets, which can cause content to shift when the status bar is shown or hidden. To avoid this implement navigatorContentInset(_:) and return insets that remain stable across status bar visibility changes, for example, a top inset large enough to accommodate the maximum expected status bar height.

From now on, content insets should include safe‑area values. If you previously supplied content-only margins, make sure to update them to add the safe-area values to preserve the same visible layout. Alternatively, a delegate hook is available to compute them consistently, helping avoid layout shifts.

Finally, as hinted to in our last What's New in Readium Mobile video, this new version of the toolkit fixes the issue of lost progression in the EPUB navigator. Reading progression is now preserved when the WebKit process is restarted by the system, but the application was not killed.

Improved text-to-speech (TTS) voice selection


Improving text-to-speech has been one of our priorities this year, and this new version of the Swift toolkit introduces two useful utilities:

  • [TTSVoice].filterByLanguage(_:) to filter voices by language and region.
  • [TTSVoice].sorted() to sort voices by region, quality and gender.

However, please note that the “eloquence” and “novelty” voices are no longer used by the PublicationSpeechSynthesizer API, as they do not align with publication‑quality narration.

Better reading highlight legibility


This new version comes with an experimental positioning of EPUB decorations that places highlights behind text for clearer, more accessible and legible annotations.

This element is available for trial via a configuration flag. To opt-in, initialize the EPUBNavigatorViewController.Configuration object with decorationTemplates: HTMLDecorationTemplate.defaultTemplates(alpha: 1.0, experimentalPositioning: true).

More flexible LCP integrations


The last area of interest in this release is Readium LCP. This new version of the toolkit includes an initializer parameter for providing a stable, app-scoped custom device identifier. Please note that we recommend you generate an app-scoped UUID and store it securely. Avoid using hardware or advertising identifiers.

In other news, it is now possible to inject an LCPL license document into a package using LCPService.injectLicenseDocument(_:in) when working outside the provided acquisition flow. From now on, the LCP License Document is accessible via publication.lcpLicense?.license even if license validation fails, making it easier to check expiration dates or trigger renewal flows.


Many thanks to Mickaël Menu, as well as Daniel Freiling, Dewan Tawsif, Konstantin Portnov and all our contributors for making this release possible!