CocoaPods 需额外添加 Readium 私有 podspec 源,否则找不到库;使用 Readium LCP 需向 EDRLab 申请私有的 R2LCPClient.framework 并按其说明配置;CBR 漫画格式与 Adobe ACS DRM 明确不支持。
swift-toolkit
readiumBSD-3-Clause活跃维护用 Swift 编写的电子书、有声书和漫画阅读工具包,支持 EPUB、PDF、CBZ 及 OPDS 目录解析,帮 iOS 开发者快速搭建阅读器。
A toolkit for ebooks, audiobooks and comics written in Swift
SPM:在 Xcode 中 File > Add Packages,包地址填 https://github.com/readium/swift-toolkit.git
CocoaPods:在 Podfile 中添加 source 'https://github.com/readium/podspecs' 与 pod 'ReadiumShared', '~> 4.0.0-alpha.2'README 未说明硬件要求;仅给出软件环境:iOS 15.0 起,需 Swift 6.0 与 Xcode 16.4(develop 分支要求 Swift 6.2、Xcode 26.4)。
Swift 编写的电子书、有声书与漫画阅读工具包,帮你快速搭建 iOS 阅读应用
用 Swift 编写的电子书、有声书和漫画阅读工具包,支持 EPUB、PDF、CBZ 及 OPDS 目录解析,帮 iOS 开发者快速搭建阅读器。
核心能力
- 解析 EPUB、PDF、RWPM 为统一的 Publication 模型
- 提供 Navigator 渲染分页、滚动与 RTL 排版
- 支持正文搜索、高亮标注与 TTS 朗读
- 内置 AudioNavigator 播放有声书与读取音频元数据
- 支持 OPDS 1.2/2.0 目录与 Readium LCP DRM
容易踩的坑
- 3.11.1最新正式版2026-10-16 · 2026-10-16 13:29 UTC
[!WARNING] Minor releases (
a.B.c) of the Readium toolkit may now include minor breaking changes, such as dependency upgrades or small API modifications. Major version numbers are reserved for significant architectural changes.Documentation
- Versioned Documentation – Complete API reference on readium.org.
- Migration Guide – Instructions for upgrading from previous versions.
Changelog
Changed
LCP
- Opening an LCP publication is no longer delayed by the CRL used to validate its license. The CRL is now downloaded when creating the
LCPService, and an expired one is refreshed in the background instead of making the user wait for the response.
Fixed
Navigator
- Fixed reflowable EPUBs being displayed as a single column on the iPhone Duo unfolded in landscape, by porting the responsive columns fix of Readium CSS 1.1.2.
LCP
- The CRL used to validate LCP licenses is now checked to be a genuine X.509 CRL before being cached. Networks with a captive portal (e.g. on a plane) could return their login page with a
200 OKstatus, which was then cached for seven days and prevented opening LCP publications. An invalid CRL cached by a previous version is now ignored instead of waiting for its expiration.
Full Changelog: https://github.com/readium/swift-toolkit/compare/3.11.0...3.11.1
- 4.0.0-alpha.2pre-release2026-09-18 · 2026-09-18 16:13 UTC
查看更新说明
[!WARNING] Minor releases (
a.B.c) of the Readium toolkit may now include minor breaking changes, such as dependency upgrades or small API modifications. Major version numbers are reserved for significant architectural changes.Documentation
- Versioned Documentation – Complete API reference on readium.org.
- Migration Guide – Instructions for upgrading from previous versions.
Changelog
Added
Navigator
- The EPUB navigator supports publications mixing reflowable and fixed-layout resources, rendering each resource according to its own layout.
- New
EPUBNavigatorViewController.Configuration.preferredResourceVariantto choose which variant of each resource is rendered among itsalternates, such as the XHTML page or its bitmap fallback.- Bitmap resources in the reading order are rendered as fixed-layout, even in a reflowable publication.
- New
EPUBNavigatorDelegate.navigator(_:contentInsetFor:)to customize the content insets of a spread according to itsEPUBLayout, for example to add margins only around the reflowable resources of a mixed-layout publication. It takes precedence overnavigatorContentInset(_:). - New
Navigator.readingOrderproperty returning the reading order actually rendered by the navigator, which may differ frompublication.readingOrderwhen a custom reading order or a resource variant is used.
Changed
Shared
- Converting a
Linkto aLocatoris now synchronous:await publication.locate(link)becomespublication.locator(for: link). The logic moved toManifest, so it is also available asmanifest.locator(for: link)without aPublication.
Navigator
- In the EPUB navigator, a fixed-layout resource displayed on its own when spreads are enabled is now centered, unless the publication provides an explicit page position (e.g.
page-spread-left). It was previously displayed on the left or right half of the viewport, depending on the reading progression.
Streamer
- EPUB spine items with a bitmap fallback are no longer swapped with their fallback. The spine item stays in the reading order and the bitmap is available in its
alternates.- This changes the resources rendered by default and the href of the reported locations. Locations saved with the previous version are still restored by the EPUB navigator.
- Use
EPUBNavigatorViewController.Configuration.preferredResourceVariant = .imagein the EPUB navigator configuration to render the bitmaps like before.
LCP
- Opening an LCP publication is no longer delayed by the CRL used to validate its license. The CRL is now downloaded when creating the
LCPService, and an expired one is refreshed in the background instead of making the user wait for the response.
Fixed
Shared
- #876 Fixed a crash (
String index is out of bounds) inContentSearchServicewhen searching a publication containing characters merging with the surrounding text, such as combining diacritical marks.
Navigator
- #121 HTML
<audio>and<video>elements are now paused when the resource moves off-screen in the EPUB navigator, rather than continuing to play in the background. - Fixed the PDF navigator's content being inset by the surrounding safe area (e.g. the navigation bar) on iOS 27.
- #112 In the paginated EPUB navigator, horizontal swipes over the top and bottom margins of a reflowable resource now turn the page, instead of skipping to the previous or next resource.
Streamer
- #85 When an EPUB declares the same metadata with both an EPUB 2
<meta name=>tag and an EPUB 3 `<meta propert
- 4.0.0-alpha.1pre-release2026-08-14 · 2026-08-14 17:42 UTC
查看更新说明
[!WARNING] Minor releases (
a.B.c) of the Readium toolkit may now include minor breaking changes, such as dependency upgrades or small API modifications. Major version numbers are reserved for significant architectural changes.Documentation
- Versioned Documentation – Complete API reference on readium.org.
- Migration Guide – Instructions for upgrading from previous versions.
Changelog
Added
Shared
- Content elements now expose
accessibleName,accessibleDescriptionandextendedDescriptionattributes, computed following a subset of the W3C accessible name computation and Best Practices for Implementing Extended Descriptions in EPUB. - The HTML content iterator now emits inline
<svg>elements asSVGContentElement, with a caption from the enclosing figure'sfigcaption. AudioContentElementandVideoContentElementnow expose acaptionproperty, filled from the enclosing figure'sfigcaptionlike images and SVGs already were.
Changed
- The toolkit is migrated to Swift 6 with strict concurrency checking. All packages compile in the Swift 6 language mode. See the migration guide.
- The toolkit adopts the
NonisolatedNonsendingByDefault(SE-0461),InferIsolatedConformancesandMemberImportVisibilityupcoming Swift features.
- The toolkit adopts the
Shared
- OPDS models (
Feed,Group,Facet,OpdsMetadata) are now structs with value semantics. Publication,Resource,Containerand related types are nowSendable. Custom implementations ofResource,Container,HTTPClientorPublicationServicemust beSendabletoo.Resource.stream()now cooperates with task cancellation: the built-in resources fail withReadError.cancelledwhen the surrounding task is cancelled, and custom implementations are expected to do the same.ImageContentElement.captionandSVGContentElement.captionare now strictly the text of the enclosing figure'sfigcaption. Other sources (such asalt) contribute toaccessibleNameinstead.- Audio and video content elements now expose accessibility attributes, so the text-to-speech may start speaking their labels.
Navigator
- The
NavigatorandVisualNavigatorprotocols and their delegates are now isolated to the main actor.
LCP
LCPService.initnow requires an explicitdeviceNameparameter. We recommend passingUIDevice.current.name. See the migration guide.LCPDialogAuthenticationno longer takes asenderview controller. It now presents its passphrase dialog through a newLCPDialogAuthenticationDelegatethat you implement and retain for the lifetime of the authentication. See the Readium LCP guide and the migration guide.
Removed
- The deprecated
ReadiumAdapterGCDWebServerandReadiumAdapterLCPSQLiteadapter packages have been removed. - The
ReadiumInternalpackage has been removed. Its utilities were internal helpers and are now folded intoReadiumSharedwithpackagevisibility. If you importedReadiumInternaldirectly, remove the import.
What's Changed
- Replace DifferenceKit and CryptoSwift with native Swift code by @stevenzeck in https://github.com/readium/swift-toolkit/pull/875
- Add missing
Sendableconformances by @mickael-menu in https://github.com/readium/swift-toolkit/pull/881 - Generate the Playground project with XcodeGen and unify the dev workflow by @stevenzeck in https://github.com/readium/swift-toolkit/pull/849
- Add accessible name and description to content elements by @mickael-menu in https://github.com/readium/swift-toolkit/pull
- 3.11.02026-07-17 · 2026-07-17 08:27 UTC
查看更新说明
[!WARNING] Minor releases (
a.B.c) of the Readium toolkit may now include minor breaking changes, such as dependency upgrades or small API modifications. Major version numbers are reserved for significant architectural changes.Documentation
- Versioned Documentation – Complete API reference on readium.org.
- Migration Guide – Instructions for upgrading from previous versions.
Changelog
Added
Navigator
- Added the
AudioSessionManagingprotocol, letting apps provide their own audio session manager instead of the built-inAudioSession(contributed by @svenmeyers89).
LCP
LCPServicehas a newaddPassphrase(_:isHashed:userID:provider:)method to store a passphrase candidate in the repository without opening a license first. Useful to preload a passphrase ahead of time (e.g. from a catalog).LCPClienthas a newgetSupportedLCPProfileURIs()requirement, letting the toolkit reportLCPError.licenseProfileNotSupportedbased on the profiles the embedded liblcp actually supports. Update yourLCPClientfacade to forwardR2LCPClient.getSupportedLCPProfileURIs()(a default implementation is provided for backward compatibility).
Changed
LCP
- The auto-generated LCP device ID is now stored in the Keychain instead of
UserDefaults, so it survives an app delete/reinstall and no longer needlessly consumes a license's device-registration slots. Existing IDs are automatically migrated fromUserDefaults.
Fixed
Shared
- EPUB HREFs that are not percent-encoded but carry a fragment or query (e.g.
chapter one.xhtml#section, with a space in the filename) now keep their#fragment/?queryinstead of encoding the separators into the path. This fixes table of contents and Media Overlays links failing to resolve and navigate in poorly-authored EPUBs.
Navigator
- Fixed custom
EditingActions sometimes missing from the text-selection menu for double-tap (single word) selections (contributed by @raphi011). - Fixed memory leak in the
AudioNavigator. - #802 Fixed fonts declared with
fontFamilyDeclarationsnever loading in the EPUB navigator. Font fetches were CORS-gated by WebKit (contributed by @atani).
What's Changed
- Replace drafts.opds.io with specs.opds.io by @mickael-menu with @Copilot in https://github.com/readium/swift-toolkit/pull/834
- Fix docs workflow root path resolution in
generate-docs.shby @mickael-menu with @Copilot in https://github.com/readium/swift-toolkit/pull/835 - Fix Authentication for OPDS URL incorrectly pointing to specs.opds.io by @mickael-menu with @Copilot in https://github.com/readium/swift-toolkit/pull/836
- Fix custom editing actions missing on double-tap selections (iOS 16+ buildMenu) by @raphi011 in https://github.com/readium/swift-toolkit/pull/822
- Add
LCPService.addPassphrase()to preload passphrases by @mickael-menu in https://github.com/readium/swift-toolkit/pull/840 - Fix memory leak in the
AudioNavigatorby @mickael-menu in https://github.com/readium/swift-toolkit/pull/842 - Improve CI and release tooling by @mickael-menu in https://github.com/readium/swift-toolkit/pull/843
- Fix fonts declared with fontFamilyDeclarations never loading by @atani in https://github.com/readium/swift-toolkit/pull/845
- Fix poorly-authored EPUB links not navigating by @mickael-menu in https://github.com/readium/swift-toolkit/pull/847
- Improve LCP profiles detection by @mickael-menu in https://github.com/readium/swift-toolkit/pull/857
- Enable external Audio Session handling by @svenmeyers89 in https://github.com/readium/swift-toolkit/pull/856
- Store the auto-gene
- 3.10.02026-06-24 · 2026-06-24 13:36 UTC
查看更新说明
[!WARNING] Minor releases (
a.B.c) of the Readium toolkit may now include minor breaking changes, such as dependency upgrades or small API modifications. Major version numbers are reserved for significant architectural changes.Documentation
- Versioned Documentation – Complete API reference on readium.org.
- Migration Guide – Instructions for upgrading from previous versions.
Changelog
Changed
LCP
LCPPassphraseRepository.addPassphrase(_:userID:provider:)no longer takes a license ID, andprovideris now optional. A convenienceaddPassphrase(_:)overload is available for storing a passphrase without any associated user or provider.
Fixed
Shared
- ZIP entry names stored with a leading slash (e.g.
/001.jpg, found in some CBZ comics) are now normalized to relative paths. Previously such entries resolved as absolute-path references against the base URL, causing them to fail.
Navigator
- Fixed EPUB footnotes never being detected when tapped, which prevented
EPUBNavigatorDelegate.navigator(_:shouldNavigateToNoteAt:content:referrer:)from being called and made footnote references navigate to the note's location instead of being handled by the host (contributed by @raphi011).
LCP
- #818 Repository failures during passphrase lookup (e.g. Keychain access errors) now fall through gracefully to the interactive authentication flow instead of propagating the error.
What's Changed
- Add release scripts by @mickael-menu in https://github.com/readium/swift-toolkit/pull/796
- Fix leading-slash ZIP entry names breaking ZIP-based publications by @raphi011 in https://github.com/readium/swift-toolkit/pull/809
- Upgrade Swift and JS dependencies by @mickael-menu in https://github.com/readium/swift-toolkit/pull/815
- Fix EPUB footnotes not being detected when tapped by @raphi011 in https://github.com/readium/swift-toolkit/pull/821
- Add LCP passphrase without a license ID or provider by @mickael-menu in https://github.com/readium/swift-toolkit/pull/824
- 3.10.0 by @mickael-menu in https://github.com/readium/swift-toolkit/pull/825
New Contributors
- @raphi011 made their first contribution in https://github.com/readium/swift-toolkit/pull/809
Full Changelog: https://github.com/readium/swift-toolkit/compare/3.9.0...3.10.0
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Readium Swift Toolkit
Readium Mobile is a toolkit for ebooks, audiobooks and comics written in Swift & Kotlin.
[!TIP] Take a look at the guide to quickly get started. A Test App demonstrates how to integrate the Readium Swift toolkit in your own reading app.
Features
✅ Implemented 🚧 Partially implemented 📆 Planned 👀 Want to do ❌ Not planned
Formats
Ebook and Document Formats
| Format | Status |
|---|---|
| EPUB (reflowable) | ✅ |
| EPUB (fixed-layout) | ✅ |
| ✅ | |
| Readium Web Publication | 🚧 |
| DAISY | 👀 |
Audiobook Formats
| Format | Status |
|---|---|
| Readium Audiobook | ✅ |
| Zipped Audiobook | ✅ |
| Standalone audio files (MP3, AAC, etc.) | ✅ |
| DAISY | 👀 |
Comic Formats
| Format | Status |
|---|---|
| Readium Divina | ✅ |
| CBZ (Comic Book ZIP) | ✅ |
| CBR (Comic Book RAR) | ❌ |
Features
A number of features are implemented only for some publication formats.
| Feature | EPUB (reflow) | EPUB (FXL) | |
|---|---|---|---|
| Pagination | ✅ | ✅ | ✅ |
| Scrolling | ✅ | 👀 | ✅ |
| Right-to-left (RTL) | ✅ | ✅ | ✅ |
| Search in textual content | ✅ | ✅ | ✅ |
| Highlighting (Decoration API) | ✅ | ✅ | 👀 |
| Text-to-speech (TTS) | ✅ | ✅ | 👀 |
| Media overlays | 📆 | 📆 |
OPDS Support
| Feature | Status |
|---|---|
| OPDS Catalog 1.2 | ✅ |
| OPDS Catalog 2.0 | ✅ |
| Authentication for OPDS | 📆 |
| OPDS Progression | 📆 |
| Readium LCP Automatic Key Retrieval | 📆 |
DRM Support
| Feature | Status |
|---|---|
| Readium LCP | ✅ |
| Adobe ACS | ❌ |
User Guides
Guides are available to help you make the most of the toolkit.
Publication
- Opening a publication – parse a publication package (EPUB, PDF, etc.) or manifest (RWPM) into Readium
Publicationmodels - Extracting the content of a publication – API to extract the text content of a publication for searching or indexing it
- Searching a publication – search the textual content of a publication and navigate to matching results
- Text-to-speech – read aloud the content of a textual publication using speech synthesis
- Accessibility – inspect accessibility metadata and present it to users
Navigator
- Navigator - an overview of the Navigator to render a
Publication's content to the user - Configuring the Navigator – setup and render Navigator user preferences (font size, colors, etc.)
- Integrating the Navigator with SwiftUI – glue to setup the Navigator in a SwiftUI application
- Implementing Highlights – add and manage highlights in a publication
- Font families in the EPUB navigator – support custom font families with reflowable EPUB publications
- EPUB image preview – detect tapped images and present an image detail view
- Playing audiobooks – play an audiobook with the
AudioNavigatorand read the metadata of audio files
DRM
- Supporting Readium LCP – open and render LCP DRM protected publications
Setting up the Readium Swift toolkit
Minimum Requirements
| Readium | iOS | Swift compiler | Xcode |
|---|---|---|---|
develop | 15.0 | 6.2 | 26.4 |
| 3.8.0 | 15.0 | 6.0 | 16.4 |
| 3.0.0 | 13.4 | 5.10 | 15.4 |
| 2.5.1 | 11.0 | 5.6.1 | 13.4 |
| 2.5.0 | 10.0 | 5.6.1 | 13.4 |
| 2.4.0 | 10.0 | 5.3.2 | 12.4 |
Dependencies
The toolkit's libraries are distributed with Swift Package Manager (recommended) and CocoaPods. It's also possible to clone the repository (or a fork) and depend on the libraries locally.
The Test App contains examples on how to use all these dependency managers.
Swift Package Manager
From Xcode, open File > Add Packages and use Readium's GitHub repository for the package URL: https://github.com/readium/swift-toolkit.git.
You are then free to add one or more Readium libraries to your application. They are designed to work independently.
If you're stuck, find more information at developer.apple.com.
CocoaPods
Add the following pod statements to your Podfile for the Readium libraries you want to use:
source 'https://github.com/readium/podspecs'
source 'https://cdn.cocoapods.org/'
pod 'ReadiumShared', '~> 4.0.0-alpha.2'
pod 'ReadiumStreamer', '~> 4.0.0-alpha.2'
pod 'ReadiumNavigator', '~> 4.0.0-alpha.2'
pod 'ReadiumOPDS', '~> 4.0.0-alpha.2'
pod 'ReadiumLCP', '~> 4.0.0-alpha.2'
Take a look at CocoaPods's documentation for more information.
Local Git Clone
You may prefer to use a local Git clone if you want to contribute to Readium, or if you are using your own fork.
First, add the repository as a Git submodule of your app repository, then checkout the desired branch or tag:
git submodule add https://github.com/readium/swift-toolkit.git
Next, drag and drop the whole swift-toolkit folder into your project to import Readium as a Swift Package.
Finally, add the Readium libraries you want to use to your app target from the General tab, section Frameworks, Libraries, and Embedded Content.
Building with Readium LCP
Using the toolkit with Readium LCP requires additional dependencies, including the framework R2LCPClient.framework provided by EDRLab. Contact EDRLab to request your private R2LCPClient.framework and the setup instructions.
Credits
This project is tested with BrowserStack.