diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 7506f124b..e284e1d36 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -28,7 +28,7 @@ jobs: run: | # Check that the Carthage project is up to date. make carthage-project - git diff --exit-code --name-only PM/Carthage/Readium.xcodeproj + git diff --exit-code --name-only Support/Carthage/Readium.xcodeproj - name: Build run: | xcodebuild build-for-testing -scheme "$scheme" -destination "platform=$platform,name=$device" diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..2fd47d96e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,381 @@ +# Changelog + +All notable changes to this project will be documented in this file. Take a look at [the migration guide](Documentation/Migration%20Guide.md) to upgrade between two major versions. + +**Warning:** Features marked as *alpha* may change or be removed in a future release without notice. Use with caution. + + + +## 2.2.0 + +### Added + +#### Shared + +* Support for Paragraph Margins user setting. + +#### Navigator + +* A new `translate` EPUB and PDF editing action is available for iOS 15. + +### Fixed + +#### Shared + +* Improved performances of the search service used with EPUB. + +#### Navigator + +* Fixed turning pages of an EPUB reflowable resource with an odd number of columns. A virtual blank trailing column is appended to the resource when displayed as two columns. + +## 2.1.1 + +### Fixed + +#### LCP + +* Fix crash using the default `LCPDialogViewController` with CocoaPods. + + +## 2.1.0 + +### Added + +* Support for Swift Package Manager (contributed by [@stevenzeck](https://github.com/stevenzeck)). + +#### Shared + +* (*alpha*) A new Publication `SearchService` to search through the resources' content with a default implementation `StringSearchService`. +* `Link` objects from archive-based publication assets (e.g. an EPUB/ZIP) have additional properties for entry metadata. + ```json + "properties" { + "archive": { + "entryLength": 8273, + "isEntryCompressed": true + } + } + ``` +* New `UserProperties.removeProperty(forReference:)` API to remove unwanted Readium CSS properties (contributed by [@ettore](https://github.com/readium/r2-shared-swift/pull/157)). + +#### Navigator + +* EPUB navigator: + * The EPUB navigator is now able to navigate to a `Locator` using its `text` context. This is useful for search results or highlights missing precise locations. + * New `EPUBNavigatorViewController.evaluateJavaScript()` API to run a JavaScript on the currently visible HTML resource. + * New `userSettings` property for `EPUBNavigatorViewController.Configuration` to set the default user settings values (contributed by [@ettore](https://github.com/readium/r2-navigator-swift/pull/191)). + * You can provide custom editing actions for the text selection menu (contributed by [@cbaltzer](https://github.com/readium/r2-navigator-swift/pull/181)). + 1. Create a custom action with, for example: `EditingAction(title: "Highlight", action: #selector(highlight:))` + 2. Then, implement the selector in one of your classes in the responder chain. Typically, in the `UIViewController` wrapping the navigator view controller. + ```swift + class EPUBViewController: UIViewController { + init(publication: Publication) { + var config = EPUBNavigatorViewController.Configuration() + config.editingActions.append(EditingAction(title: "Highlight", action: #selector(highlight))) + let navigator = EPUBNavigatorViewController(publication: publication, config: config) + } + + @objc func highlight(_ sender: Any) {} + } + ``` +* New `SelectableNavigator` protocol for navigators supporting user selection. + * Get or clear the current selection. + * Implement `navigator(_:canPerformAction:for:)` to validate each editing action for the current selection. For example, to make sure the selected text is not too large for a definition look up. + * Implement `navigator(_:shouldShowMenuForSelection:)` to override the default edit menu (`UIMenuController`) with a custom selection pop-up. +* (*alpha*) Support for the [Decorator API](https://github.com/readium/architecture/pull/160) to draw user interface elements over a publication's content. + * This can be used to render highlights over a text selection, for example. + * For now, only the EPUB navigator implements `DecorableNavigator`. You can implement custom decoration styles with `HTMLDecorationTemplate`. +* (*alpha*) A new navigator for audiobooks. + * The navigator is chromeless, so you will need to provide your own user interface. + +### Deprecated + +#### Navigator + +* Removed `navigator(_:userContentController:didReceive:)` which is actually not needed since you can provide your own `WKScriptMessageHandler` to `WKUserContentController`. + +### Changed + +#### Streamer + +* The default EPUB positions service now uses the archive entry length when available. [This is similar to how Adobe RMSDK generates page numbers](https://github.com/readium/architecture/issues/123). + * To use the former strategy, create the `Streamer` with: `Streamer(parsers: [EPUBParser(reflowablePositionsStrategy: .originalLength(pageLength: 1024))])` + +### Fixed + +#### Streamer + +* [#208](https://github.com/readium/r2-streamer-swift/issues/208) Crash when reading obfuscated EPUB resources with an empty publication identifier. + +#### Navigator + +* Fixed receiving `EPUBNavigatorDelegate.navigator(_:setupUserScripts:)` for the first web view. +* [r2-testapp-swift#343](https://github.com/readium/r2-testapp-swift/issues/343) Fixed hiding "Share" editing action (contributed by [@rocxteady](https://github.com/readium/r2-navigator-swift/pull/149)). + + +## 2.0.1 + +### Fixed + +#### Shared + +* [#139](https://github.com/readium/r2-shared-swift/pull/139) Compile error with Xcode 12.4 + + +## 2.0.0 + +### Deprecated + +* All APIs deprecated in previous versions are now unavailable. + +#### Shared + +* `DownloadSession` is deprecated and will be removed in the next major version. Please migrate to your own download solution. + + +## 2.0.0-beta.2 + +### Added + +#### Shared + +* `Resource` has a new API to perform progressive asynchronous reads. This is useful when streaming a resource. +* `HTTPFetcher` is a new publication fetcher able to serve remote resources through HTTP. + * The actual HTTP requests are performed with an instance of `HTTPClient`. +* `HTTPClient` is a new protocol exposing a high level API to perform HTTP requests. + * It supports simple fetches but also progressive downloads. + * `DefaultHTTPClient` is an implementation of `HTTPClient` using standard `URLSession` APIs. You can use its delegate to customize how requests are created and even recover from errors, e.g. to implement Authentication for OPDS. + * You can provide your own implementation of `HTTPClient` to Readium APIs if you prefer to use a third-party networking library. +* `PublicationServiceContext` now holds a weak reference to the parent `Publication`. This can be used to access other services from a given `PublicationService` implementation. +* The default `LocatorService` implementation can be used to get a `Locator` from a global progression in the publication. + * `publication.locate(progression: 0.5)` + +#### Streamer + +* `Streamer` takes a new optional `HTTPClient` dependency to handle HTTP requests. + +#### Navigator + +* New `EPUBNavigatorDelegate` APIs to inject custom JavaScript. + * Override `navigator(_:setupUserScripts:)` to register additional user script to the `WKUserContentController` of each web view. + * Override `navigator(_:userContentController:didReceive:)` to receive callbacks from your scripts. + +### Changed + +#### Shared + +* The `Archive` API now supports resource ownership at the entry level. + * The default ZIP implementation takes advantage of this by opening a new ZIP stream for each resource to be served. This improves performances and memory safety. + +#### Streamer + +* The HTTP server now requests that publication resources are not cached by browsers. + * Caching poses a security risk for protected publications. + +#### LCP + +* We removed the dependency to the private `R2LCPClient.framework`, which means: + * Now `r2-lcp-swift` works as a Carthage dependency, no need to use a submodule anymore. + * You do not need to modify `r2-lcp-swift`'s `Cartfile` anymore to add the private `liblcp` dependency. + * However, you must provide a facade to `LCPService` (see [README](README.md) for an example implementation). +* The Renew Loan API got revamped to better support renewal through a web page. + * You will need to implement `LCPRenewDelegate` to coordinate the UX interaction. + * Readium ships with a default implementation `LCPDefaultRenewDelegate` to handle web page renewal with `SFSafariViewController`. + +### Fixed + +#### Shared + +* Improved performances when reading consecutive ranges of a deflated ZIP entry. +* HREF normalization when a resource path contains special characters. + +#### Navigator + +* Optimized performances of preloaded EPUB resources. + +#### LCP + +* Fixed really slow opening of large PDF documents. + + +## 2.0.0-beta.1 + +### Added + +#### Shared + +* `PublicationAsset` is a new protocol which can be used to open a publication from various medium, such as a file, a remote URL or a custom source. + * `File` was replaced by `FileAsset`, which implements `PublicationAsset`. + +### Changed + +#### Shared + +* `Format` got merged into `MediaType`, to simplify the media type APIs. + * You can use `MediaType.of()` to sniff the type of a file or bytes. + * `MediaType` has now optional `name` and `fileExtension` properties. + * Some publication formats can be represented by several media type aliases. Using `mediaType.canonicalized` will give you the canonical media type to use, for example when persisting the file type in a database. All Readium APIs are already returning canonical media types, so it only matters if you create a `MediaType` yourself from its string representation. +* `ContentLayout` is deprecated, use `publication.metadata.effectiveReadingProgression` to determine the reading progression of a publication instead. + +#### Streamer + +* `Streamer` is now expecting a `PublicationAsset` instead of a `File`. You can create custom implementations of +`PublicationAsset` to open a publication from different medium, such as a file, a remote URL, in-memory bytes, etc. + * `FileAsset` can be used to replace `File` and provides the same behavior. + +### Fixed + +#### Navigator + +* EPUBs declaring multiple languages were laid out from right to left if the first language had an RTL reading +progression. Now if no reading progression is set, the `effectiveReadingProgression` will be LTR. + + +## 2.0.0-alpha.2 + +### Added + +#### Shared + +* The [Publication Services API](https://readium.org/architecture/proposals/004-publication-helpers-services) allows to extend a `Publication` with custom implementations of known services. This version ships with a few predefined services: + * `PositionsService` provides a list of discrete locations in the publication, no matter what the original format is. + * `CoverService` provides an easy access to a bitmap version of the publication cover. +* The [Composite Fetcher API](https://readium.org/architecture/proposals/002-composite-fetcher-api) can be used to extend the way publication resources are accessed. +* Support for exploded directories for any archive-based publication format. +* [Content Protection](https://readium.org/architecture/proposals/006-content-protection) handles DRM and other format-specific protections in a more systematic way. + * LCP now ships an `LCPContentProtection` implementation to be plugged into the `Streamer`. + * You can add custom `ContentProtection` implementations to support other DRMs by providing an instance to the `Streamer`. +* A new `LinkRelation` type to represent link relations, instead of using raw strings. + * This will improve code safety through type checking and enable code completion. + * Since `LinkRelation` conforms to `ExpressibleByStringLiteral`, you can continue using raw strings in the API. However, migrating your code is recommended, e.g. `links.first(withRel: .cover)`. + * Known link relations (including from OPDS specifications) are available under the `LinkRelation` namespace. You can easily add custom relations to the namespace by declaring `static` properties in a `LinkRelation` extension. + +#### Streamer + +* [Streamer API](https://readium.org/architecture/proposals/005-streamer-api) offers a simple interface to parse a publication and replace standalone parsers. +* A generic `ImageParser` for bitmap-based archives (CBZ or exploded directories) and single image files. +* A generic `AudioParser` for audio-based archives (Zipped Audio Book or exploded directories) and single audio files. + +#### Navigator + +* Support for the new `Publication` model using the [Content Protection](https://readium.org/architecture/proposals/006-content-protection) for DRM rights and the [Fetcher](https://readium.org/architecture/proposals/002-composite-fetcher-api) for resource access. + * This replaces the `Container` and `DRMLicense` objects which were needed by the navigator before. + +#### LCP + +* LCP implementation of the [Content Protection API](https://readium.org/architecture/proposals/006-content-protection) to work with the new [Streamer API](https://readium.org/architecture/proposals/005-streamer-api). + * It is highly recommended that you upgrade to the new `Streamer` API to open publications, which will simplify DRM unlocking. +* Two default implementations of `LCPAuthenticating`: + * `LCPDialogAuthentication` to prompt the user for its passphrase with the official LCP dialog. + * `LCPPassphraseAuthentication` to provide directly a passphrase, pulled for example from a database or a web service. +* `LCPService.acquirePublication()` is a new API to acquire a publication from a standalone license. Compared to the former `importPublication()`: + * It doesn't require the passphrase, to allow bulk imports. + * It can be cancelled by calling `cancel()` on the returned `LCPAcquisition` object. +* `LCPService.isLCPProtected()` provides a way to check if a file is protected with LCP. + +### Changed + +#### Shared + +* [The `Publication` and `Container` types were merged together](https://readium.org/architecture/proposals/003-publication-encapsulation) to offer a single interface to a publication's resources. + * Use `publication.get()` to read the content of a resource, such as the cover. It will automatically be decrypted if a `ContentProtection` was attached to the `Publication`. + +#### Streamer + +* `Container` and `ContentFilters` were replaced by a shared implementation of a [`Fetcher`](https://readium.org/architecture/proposals/002-composite-fetcher-api). +* `PDFFileParser` was replaced in favor of a shared `PDFDocument` protocol. This version ships with two implementations using PDFKit and CoreGraphics. + +#### LCP + +* `LCPAuthenticating` is now provided with more information and you will need to update your implementation. + +### Fixed + +#### Streamer + +* Deobfuscating ranges of EPUB resources. + +#### Navigator + +* Layout of right-to–left EPUB. +* [Various EPUB navigation issues](https://github.com/readium/r2-navigator-swift/pull/142): + * Prevent breaking initial location when calling `updateUserSettings` too soon. + * Fix weird scrolling behavior when double tapping on the edges to turn pages. + * Don't send intermediate incorrect locators when loading a pending locator. +* Optimize positions calculation for LCP protected PDF. + +#### LCP + +* [Decrypting resources in some edge cases](https://github.com/readium/r2-lcp-swift/pull/94). + + +## 2.0.0-alpha.1 + +### Added + +#### Shared + +* The new [Format API](https://readium.org/architecture/proposals/001-format-api.md) simplifies the detection of file formats, including known publication formats such as EPUB and PDF. + * [A format can be "sniffed"](https://readium.org/architecture/proposals/001-format-api.md#sniffing-the-format-of-raw-bytes) from files, raw bytes or even HTTP responses. + * Reading apps are welcome to [extend the API with custom formats](https://readium.org/architecture/proposals/001-format-api.md#supporting-a-custom-format). + * Using `Link.mediaType?.matches()` is now recommended [to safely check the type of a resource](https://readium.org/architecture/proposals/001-format-api.md#mediatype-class). + * [More details about the Swift implementation can be found in the pull request.](https://github.com/readium/r2-shared-swift/pull/88) +* In `Publication` shared models: + * [Presentation Hints](https://readium.org/webpub-manifest/extensions/presentation.html) and [HTML Locations](https://readium.org/architecture/models/locators/extensions/html.md) extensions. + * Support for OPDS holds, copies and availability in `Link`, for library-specific features. +* (*alpha*) Audiobook toolkit: + * [`AudioSession`](https://github.com/readium/r2-shared-swift/pull/91) simplifies the setup of an `AVAudioSession` and handling its interruptions. + * [`NowPlayingInfo`](https://github.com/readium/r2-shared-swift/pull/91) helps manage the ["Now Playing"](https://developer.apple.com/documentation/mediaplayer/becoming_a_now_playable_app) information displayed on the lock screen. + +#### Streamer + +* `ReadiumWebPubParser` to parse all Readium Web Publication profiles, including [Audiobooks](https://readium.org/webpub-manifest/extensions/audiobook.html) and [LCP for PDF](https://readium.org/lcp-specs/notes/lcp-for-pdf.html). It parses both manifests and packages. + +#### Navigator + +* Support for pop-up footnotes (contributed by [@tooolbox](https://github.com/readium/r2-navigator-swift/pull/118)). + * **This is an opt-in feature**. Reading apps can customize how footnotes are presented to the user by implementing `NavigatorDelegate.navigator(_:shouldNavigateToNoteAt:content:referrer:)`. [An example presenting footnotes in pop-ups is demonstrated in the Test App](https://github.com/readium/r2-testapp-swift/pull/328). + * Footnotes' content is extracted with [scinfu/SwiftSoup](https://github.com/scinfu/SwiftSoup), which you may need to add to your app if you're not using Carthage or CocoaPods. +* In EPUB's user settings: + * Support for hyphenation (contributed by [@ehapmgs](https://github.com/readium/r2-navigator-swift/pull/76)). + * Publishers' default styles are now used by default. + * Default line height is increased to improve readability. +* JavaScript errors are logged in Xcode's console for easier debugging. + +#### LCP + +* Support for [PDF](https://readium.org/lcp-specs/notes/lcp-for-pdf.html) and [Readium Audiobooks](https://readium.org/lcp-specs/notes/lcp-for-audiobooks.html) protected with LCP. + +### Changed + +#### Shared + +* All the `Publication` shared models are now immutable, to improve code safety. This should not impact reading apps unless you created `Publication` or other models yourself. +* The `DocumentTypes` API was extended and [offers an easy way to check if your app supports a given file](https://github.com/readium/r2-testapp-swift/pull/325/files#diff-afef0c51328e306d131d64cdf716a1d1R21-R24). +* Dependencies to format-related third-party libraries such as ZIP, XML and PDF are being consolidated into `r2-shared-swift`. Therefore, `r2-shared-swift` now depends on Fuzi and ZIPFoundation. This change will improve maintainability by isolating third-party code and allow (work in progress) to substitute the default libraries with custom ones. + +#### Navigator + +* [Upgraded to Readium CSS 1.0.0-beta.1.](https://github.com/readium/r2-navigator-swift/pull/125) + * Two new fonts are available: AccessibleDfa and IA Writer Duospace. + * The file structure now follows strictly the one from [ReadiumCSS's `dist/`](https://github.com/readium/readium-css/tree/master/css/dist), for easy upgrades and custom builds replacement. + +#### LCP + +* `LCPAuthenticating` can now return hashed passphrases in addition to clear ones. [This can be used by reading apps](https://github.com/readium/r2-lcp-swift/pull/75) fetching hashed passphrases from a web service or [Authentication for OPDS](https://readium.org/lcp-specs/notes/lcp-key-retrieval.html), for example. +* Provided `LCPAuthenticating` instances are now retained by the LCP service. Therefore, you can provide one without keeping a reference around in your own code. + +### Fixed + +#### Streamer + +* Significant performance improvement when opening PDF documents protected with LCP. +* [Prevent the embedded HTTP server from stopping when the device is locked](https://github.com/readium/r2-streamer-swift/pull/163), to allow background playback of audiobooks. + +#### Navigator + +* Jumping to a bookmark (`Locator`) located in a resource that is not already pre-loaded used to fail for some publications. +* Touching interactive elements in fixed-layout EPUBs, when two-page spreads are enabled. + + +[unreleased]: https://github.com/readium/swift-toolkit/compare/main...HEAD +[2.2.1]: https://github.com/readium/swift-kotlin/compare/2.2.0...2.2.1 diff --git a/Documentation/Migration Guide.md b/Documentation/Migration Guide.md new file mode 100644 index 000000000..041c30410 --- /dev/null +++ b/Documentation/Migration Guide.md @@ -0,0 +1,374 @@ +# Migration Guide + +All migration steps necessary in reading apps to upgrade to major versions of the Swift Readium toolkit will be documented in this file. + +## 2.2.0 + +With this new release, we migrated all the [`r2-*-swift`](https://github.com/readium/?q=r2-swift) repositories to [a single `swift-toolkit` repository](https://github.com/readium/r2-testapp-swift/issues/404). + +The same Readium libraries are available as before, but you will need to update the configuration of your dependency manager. + +### Using Swift Package Manager + +With SPM, instead of having one Swift Package per Readium library, we now have a single Readium Swift Package offering one product per Readium library. + +First, remove all the Readium Swift Packages from your project setting, from the tab **Package Dependencies**. Then, add the new Swift Package using the following URL `https://github.com/readium/swift-toolkit.git`. + +Xcode will then ask you which Package Product you want to add to your app. Add the ones you were using previously. + +That's all, your project should build successfully. + +### Using Carthage + +Just replace the former Readium `Cartfile` statements with the new one: + +```diff ++github "readium/swift-toolkit" ~> 2.2.0 +-github "readium/r2-shared-swift" ~> 2.2.0 +-github "readium/r2-streamer-swift" ~> 2.2.0 +-github "readium/r2-navigator-swift" ~> 2.2.0 +-github "readium/r2-opds-swift" ~> 2.2.0 +-github "readium/r2-lcp-swift" ~> 2.2.0 +``` + +Then, rebuild the libraries using `carthage update --platform ios --use-xcframeworks --cache-builds`. Carthage will build all the Readium libraries and their dependencies, but you are free to add only the ones you are using as before. Take a look at the [README](../README.md#carthage) for more information. + +### Using CocoaPods + +If you are using CocoaPods, you will need to update the URL to the Podspecs in your `Podfile`: + +```diff ++ pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumShared.podspec' ++ pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumStreamer.podspec' ++ pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumNavigator.podspec' ++ pod 'ReadiumOPDS', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumOPDS.podspec' ++ pod 'ReadiumLCP', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumLCP.podspec' + +- pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/r2-shared-swift/2.2.0/R2Shared.podspec' +- pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/r2-streamer-swift/2.2.0/R2Streamer.podspec' +- pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/r2-navigator-swift/2.2.0/R2Navigator.podspec' +- pod 'ReadiumOPDS', podspec: 'https://raw.githubusercontent.com/readium/r2-opds-swift/2.2.0/ReadiumOPDS.podspec' +- pod 'ReadiumLCP', podspec: 'https://raw.githubusercontent.com/readium/r2-lcp-swift/2.2.0/ReadiumLCP.podspec' +``` + +Then, run `pod install` to update your project. + +### Using a fork + +If you are integrating your own forks of the Readium modules, you will need to migrate them to a single fork and port your changes. Follow strictly the given steps and it should go painlessly. + +1. Upgrade your forks to the latest Readium 2.2.0 version from the legacy repositories, as you would with any update. The 2.2.0 version is available on both the legacy repositories and the new `swift-toolkit` one. It will be used to port your changes over to the single repository. +2. [Fork the new `swift-toolkit` repository](https://github.com/readium/swift-toolkit/fork) on your own GitHub space. +3. In a new local directory, clone your legacy forks as well as the new single fork: + ```sh + mkdir readium-migration + cd readium-migration + + # Clone the legacy forks + git clone https://github.com/USERNAME/r2-shared-swift.git + git clone https://github.com/USERNAME/r2-streamer-swift.git + git clone https://github.com/USERNAME/r2-navigator-swift.git + git clone https://github.com/USERNAME/r2-opds-swift.git + git clone https://github.com/USERNAME/r2-lcp-swift.git + + # Clone the new single fork + git clone https://github.com/USERNAME/swift-toolkit.git + ``` +4. Reset the new fork to be in the same state as the 2.2.0 release. + ```sh + cd swift-toolkit + git reset --hard 2.2.0 + ``` +5. For each Readium module, port your changes over to the new fork. + ```sh + rm -rf Sources/*/* + + # Copy module sources + cp -r ../r2-shared-swift/r2-shared-swift/* Sources/Shared + cp -r ../r2-streamer-swift/r2-streamer-swift/* Sources/Streamer + cp -r ../r2-navigator-swift/r2-navigator-swift/* Sources/Navigator + cp -r ../r2-opds-swift/readium-opds/* Sources/OPDS + cp -r ../r2-lcp-swift/readium-lcp-swift/* Sources/LCP + + # Remove obsolete files + rm -rf Sources/*/Info.plist + rm -rf Sources/*/*.h + ``` +6. Review your changes, then commit. + ```sh + git add Sources + git commit -m "Apply local changes to Readium" + ``` +7. Finally, pull the changes to upgrade to the latest version of the fork. You might need to fix some conflicts. + ```sh + git pull --rebase + git push + ``` + +Your fork is now ready! To integrate it in your app as a local Git clone or submodule, follow the instructions from the [README](../README.md). + + +## [2.0.0](https://github.com/readium/r2-testapp-swift/compare/2.2.0-beta.2...2.2.0) + +Nothing to change in your app to upgrade from 2.0.0-beta.2 to the final 2.0.0 release! Please follow the relevant sections if you are upgrading from an older version. + +R2 modules are referencing regular `.framework` files again instead of XCFrameworks, [to fix an issue with Xcode 12.5](https://github.com/readium/r2-testapp-swift/issues/351#issuecomment-829250100). No change should be needed in your app though. + +Note that all the APIs marked as deprecated in previous versions are now unavailable. You will need to follow the warning instructions if you were still using them. + + +## [2.0.0-beta.2](https://github.com/readium/r2-testapp-swift/compare/2.2.0-beta.1...2.2.0-beta.2) + +This is the last beta before the final 2.0.0 release. + +### Using XCFrameworks to build with Xcode 12 + +This new version requires Xcode 12 and Carthage 0.37.0 to work and is now using XCFrameworks for its dependencies. You will need to upgrade your app to use XCFrameworks as well. + +Migrating a project to XCFrameworks is [explained on Carthage's repository](https://github.com/Carthage/Carthage#migrating-a-project-from-framework-bundles-to-xcframeworks) and you can see [an example of how it was done in `r2-testapp-swift`](https://github.com/readium/r2-testapp-swift/commit/1a3fc2bb25f0d1cf17a60e7cdb8756a0dbb6a3f6). Here is a breakdown of the steps to follow: + +1. Delete your `Carthage/Build` folders to remove any existing framework bundles. +2. Upgrade your `Cartfile` to the latest dependency versions (see `r2-testapp-swift`). +3. Clear Carthage and Xcode's cache + ```shell + $ rm -rf ~/Library/Developer/Xcode/DerivedData + $ rm -rf ~/Library/Caches/org.carthage.CarthageKit + $ rm -rf ~/Library/Caches/carthage + ``` +4. Run `carthage update --use-xcframeworks --platform ios --cache-builds` to build the XCFrameworks. +5. Remove references to the old frameworks in each of your targets: + * **WARNING**: `R2LCPClient.framework` is not XCFramework-ready, so you need to keep it as-is. + * Delete references to Carthage frameworks from the target's **Frameworks, Libraries, and Embedded Content** section and/or its **Link Binary with Libraries** build phase. + * Delete references to Carthage frameworks from any **Copy Files** build phases. + * Remove all Carthage frameworks except `R2LCPClient.framework` from the target's `carthage copy-frameworks` build phase, if present. +6. Add references to XCFrameworks in each of your targets: + * In the **General** settings tab, in the **Frameworks, Libraries, and Embedded Content** section, drag and drop each XCFramework from the `Carthage/Build` folder on disk. + +#### Troubleshooting + +If after migrating to XCFrameworks you experience some build issues like **Could not find module 'R2Shared' for target 'X'**, try building the `r2-shared-swift` target with Xcode manually, before building your app. If you know of a better way to handle this, [please share it with the community](https://github.com/readium/r2-testapp-swift/issues/new). + +### LCP + +#### Providing `liblcp`/`R2LCPClient` to `r2-lcp-swift` + +[The dependency to `R2LCPClient.framework` was removed from `r2-lcp-swift`](https://github.com/readium/r2-lcp-swift/pull/112), which means: + * Now `r2-lcp-swift` works as a regular Carthage dependency, you do not need to use a submodule anymore. + * You do not need to modify `r2-lcp-swift`'s `Cartfile` anymore to add the private `liblcp` dependency. + +However, you must provide a `R2LCPClient` facade to `LCPService` in your app. [See `r2-lcp-swift`'s README for up-to-date explanation](https://github.com/readium/r2-lcp-swift) or use the following snippet. + +```swift +import R2LCPClient +import ReadiumLCP + +let lcpService = LCPService(client: LCPClient()) + +/// Facade to the private R2LCPClient.framework. +class LCPClient: ReadiumLCP.LCPClient { + + func createContext(jsonLicense: String, hashedPassphrase: String, pemCrl: String) throws -> LCPClientContext { + return try R2LCPClient.createContext(jsonLicense: jsonLicense, hashedPassphrase: hashedPassphrase, pemCrl: pemCrl) + } + + func decrypt(data: Data, using context: LCPClientContext) -> Data? { + return R2LCPClient.decrypt(data: data, using: context as! DRMContext) + } + + func findOneValidPassphrase(jsonLicense: String, hashedPassphrases: [String]) -> String? { + return R2LCPClient.findOneValidPassphrase(jsonLicense: jsonLicense, hashedPassphrases: hashedPassphrases) + } + +} +``` + +##### Troubleshooting + +If you experience the following crash during runtime: + +> dyld: Library not loaded: @rpath/R2LCPClient.framework/R2LCPClient + +Make sure you embed the `R2LCPClient.framework` with a **Copy Carthage Frameworks** build phase. [See Carthage's README](https://github.com/Carthage/Carthage). + +#### New loan renew API + +[The Renew Loan LCP API got revamped](https://github.com/readium/r2-lcp-swift/pull/107) to better support Web vs PUT interactions. You need to provide an implementation of `LCPRenewDelegate` to `LCPLicense::renewLoan()`. Readium ships with a default `LCPDefaultRenewDelegate` implementation using `SFSafariViewController` for web interactions. + +[See this commit for a migration example in `r2-testapp-swift`](https://github.com/readium/r2-testapp-swift/commit/79a00703c854a52b2272c042fd44e3bbabfeee8a). + +## [2.0.0-beta.1](https://github.com/readium/r2-testapp-swift/compare/2.2.0-alpha.2...2.2.0-beta.1) + +The version 2.0.0-beta.1 is mostly stabilizing the new APIs and fixing existing bugs. There's only two changes which might impact your codebase. + +### Replacing `Format` by `MediaType` + +To simplify the new format API, [we merged `Format` into `MediaType`](https://github.com/readium/architecture/pull/145) to offer a single interface. If you were using `Format`, you should be able to replace it by `MediaType` seamlessly. + +### Replacing `File` by `FileAsset` + +[`Streamer.open()` is now expecting an implementation of `PublicationAsset`](https://github.com/readium/architecture/pull/147) instead of an instance of `File`. This allows to open publications which are not represented as files on the device. For example a stream, an URL or any other custom structure. + +Readium ships with a default implementation named `FileAsset` replacing the previous `File` type. The API is the same so you can just replace `File` by `FileAsset` in your project. + + +## [2.0.0-alpha.2](https://github.com/readium/r2-testapp-swift/compare/2.2.0-alpha.1...2.2.0-alpha.2) + +The 2.0.0 introduces numerous new APIs in the Shared Models, Streamer and LCP libraries, which are detailed in the following proposals. We highly recommend skimming over the "Developer Guide" section of each proposal before upgrading to this new major version. + +* [Format API](https://readium.org/architecture/proposals/001-format-api) +* [Composite Fetcher API](https://readium.org/architecture/proposals/002-composite-fetcher-api) +* [Publication Encapsulation](https://readium.org/architecture/proposals/003-publication-encapsulation) +* [Publication Helpers and Services](https://readium.org/architecture/proposals/004-publication-helpers-services) +* [Streamer API](https://readium.org/architecture/proposals/005-streamer-api) +* [Content Protection](https://readium.org/architecture/proposals/006-content-protection) + +[This `r2-testapp-swift` commit](https://github.com/readium/r2-testapp-swift/commit/f2f7ed059c4159dfde0549968aa3c564b8278a16) showcases all the changes required to upgrade the Test App. + +[Please reach out on Slack](http://readium-slack.herokuapp.com/) if you have any issue migrating your app to Readium 2.0.0, after checking the [troubleshooting section](#troubleshooting). + +### Replacing the Parsers with `Streamer` + +Whether you were using individual `PublicationParser` implementations or `Publication.parse()` to open a publication, you will need to replace them by an instance of `Streamer` instead. + +#### Opening a Publication + +Call `Streamer::open()` to parse a publication. It will return asynchronously a self-contained `Publication` model which handles metadata, resource access and DRM decryption. This means that `Container`, `PubBox` and `DRM` are not needed anymore, you can remove any reference from your app. + +The `allowUserInteraction` parameter should be set to `true` if you intend to render the parsed publication to the user. It will allow the Streamer to display interactive dialogs, for example to enter DRM credentials. You can set it to `false` if you're parsing a publication in a background process, for example during bulk import. + +```swift +let streamer = Streamer() + +streamer.open(file: File(url: url), allowUserInteraction: true) { result in + switch result { + case .success(let publication): + // ... + case .failure(let error): + alert(error.localizedDescription) + case .cancelled: + break + } +} +``` + +#### Error Feedback + +In case of failure, a `Publication.OpeningError` is returned. It implements `LocalizedError` and can be used directly to present an error message to the user. + +If you wish to customize the error messages or add translations, you can override the strings declared in `r2-shared-swift/Resources/Localizable.strings` in your own app bundle. This goes for LCP errors as well, which are declared in `readium-lcp-swift/Resources/Localizable.strings`. + +#### Advanced Usage + +`Streamer` offers other useful APIs to extend the capabilities of the Readium toolkit. Take a look at its documentation for more details, but here's an overview: + +* Add new custom parsers. +* Integrated DRM support, such as LCP. +* Provide different implementations for third-party tools, e.g. ZIP, PDF and XML. +* Customize the `Publication`'s metadata or `Fetcher` upon creation. +* Collect authoring warnings from parsers. + +### Extracting Publication Covers + +Extracting the cover of a publication for caching purposes can be done with a single call to `publication.cover`, instead of reaching for a `Link` with `cover` relation. You can use `publication.coverFitting(maxSize:)` to select the best resolution without exceeding a given size. It can be useful to avoid saving very large cover images. + +```diff +-let cover = publication.coverLink +- .flatMap { try? container.data(relativePath: $0.href) } +- .flatMap { UIImage(data: $0) } + ++let cover = publication.coverFitting(maxSize: CGSize(width: 100, height: 100)) +``` + +### LCP and Other DRMs + +#### Opening an LCP Protected Publication + +Support for LCP is now fully integrated with the `Streamer`, which means that you don't need to retrieve the LCP license and fill `container.drm` yourself after opening a `Publication` anymore. + +To enable the support for LCP in the `Streamer`, you need to initialize it with a `ContentProtection` implementation provided by `r2-lcp-swift`. + +```swift +let lcpService = LCPService() +let streamer = Streamer( + contentProtections: [ + lcpService.contentProtection() + ] +) +``` + +Then, to prompt the user for their passphrase, you need to set `allowUserInteraction` to `true` and provide the instance of the hosting `UIViewController` with the `sender` parameter when opening the publication. + +```swift +streamer.open(file: File(url: url), allowUserInteraction: true, sender: hostViewController) +``` + +Alternatively, if you already have the passphrase, you can pass it directly to the `credentials` parameter. If it's valid, the user won't be prompted. + +#### Customizing the Passphrase Dialog + +The LCP Service now ships with a default passphrase dialog. You can remove the former implementation from your app if you copied it from the test app. But if you still want to use a custom implementation of `LCPAuthenticating`, for example to have a different layout, you can pass it when creating the `ContentProtection`. + +```swift +lcpService.contentProtection(with: CustomLCPAuthentication()) +``` + +#### Presenting a Protected Publication with a Navigator + +In case the credentials were incorrect or missing, the `Streamer` will still return a `Publication`, but in a "restricted" state. This allows reading apps to import publications by accessing their metadata without having the passphrase. + +But if you need to present the publication with a Navigator, you will need to first check if the `Publication` is not restricted. + +Besides missing credentials, a publication can be restricted if the Content Protection returned an error, for example when the publication is expired. In which case, you must display the error to the user by checking the presence of a `publication.protectionError`. + +```swift +if !publication.isRestricted { + presentNavigator(publication) + +} else if let error = publication.protectionError { + // A status error occurred, for example the publication expired + alert(error) + +} else { + // User cancelled the unlocking, for example by dismissing a passphrase dialog. +} +``` + +#### Accessing an LCP License Information + +To check if a publication is protected with a known DRM, you can use `publication.isProtected`. + +If you need to access an LCP license's information, you can use the helper `publication.lcpLicense`, which will return the `LCPLicense` if the publication is protected with LCP and the passphrase was known. Alternatively, you can use `LCPService::retrieveLicense()` as before. + +#### Acquiring a Publication from an LCPL + +`LCPService.importPublication()` was replaced with `acquirePublication()`, which returns a cancellable task. It doesn't require the user to enter its passphrase anymore to download the publication. + +```swift +let acquisition = lcpService.acquirePublication( + from: lcpl, + onProgress: { progress in ... }, + completion: { result in ... } +) +acquisition.cancel() +``` + +#### Supporting Other DRMs + +You can integrate additional DRMs, such as Adobe ACS, by implementing the `ContentProtection` protocol. This will provide first-class support for this DRM in the Streamer and Navigator. + +Take a look at the [Content Protection](https://readium.org/architecture/proposals/006-content-protection) proposal for more details. [An example implementation can be found in `r2-lcp-swift`](https://github.com/readium/r2-lcp-swift/tree/develop/readium-lcp-swift/Content%20Protection). + +### Troubleshooting + +#### Tried to present the LCP dialog without providing a `UIViewController` as `sender` + +To be able to present the LCP passphrase dialog, the default `LCPDialogAuthentication` needs a hosting view controller as context. You must provide it to the `sender` parameter of `Streamer::open()`, if `allowUserInteraction` is true. + +```swift +streamer.open(file: File(url: url), allowUserInteraction: true, sender: hostViewController) +``` + +#### Assertion failed: The provided publication is restricted. Check that any DRM was properly unlocked using a Content Protection. + +Navigators will refuse to be opened if a publication is protected and not unlocked. You must check if a publication is not restricted by following [these instructions](#presenting-a-protected-publication-with-a-navigator). + diff --git a/Makefile b/Makefile index 44fce9d7b..18ef3ac3a 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ help: .PHONY: carthage-project carthage-project: - xcodegen -s PM/Carthage/project.yml --use-cache --cache-path PM/Carthage/.xcodegen + xcodegen -s Support/Carthage/project.yml --use-cache --cache-path Support/Carthage/.xcodegen .PHONY: scripts scripts: diff --git a/README.md b/README.md new file mode 100644 index 000000000..c6b21df06 --- /dev/null +++ b/README.md @@ -0,0 +1,87 @@ +# Readium Swift Toolkit + +[Readium Mobile](https://github.com/readium/mobile) is a toolkit for ebooks, audiobooks and comics written in Swift & Kotlin. + +This toolkit is a modular project, which follows the [Readium Architecture](https://github.com/readium/architecture). + +* [`R2Shared`](Sources/Shared) – Shared `Publication` models and utilities +* [`R2Streamer`](Sources/Streamer) – Publication parsers and local HTTP server +* [`R2Navigator`](Sources/Navigator) – Plain `UIViewController` classes rendering publications +* [`ReadiumOPDS`](Sources/OPDS) – Parsers for OPDS catalog feeds +* [`ReadiumLCP`](Sources/LCP) – Service and models for [Readium LCP](https://www.edrlab.org/readium-lcp/) + +A [Test App](TestApp) demonstrates how to integrate the Readium Swift toolkit in your own reading app + +## Using Readium + + + +Readium libraries are distributed with [Swift Package Manager](#swift-package-manager) (recommended), [Carthage](#carthage) and [CocoaPods](#cocoapods). It's also possible to clone the repository (or a fork) and [depend on the libraries locally](#local-git-clone). + +The [Test App](TestApp) 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](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app). + +### Carthage + +Add the following to your `Cartfile`: + +``` +github "readium/swift-toolkit" ~> 2.2.0 +``` + +Then, [follow the usual Carthage steps](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add the Readium libraries to your project. + +Note that Carthage will build all Readium modules and their dependencies, but you are free to add only the ones you are actually using. The Readium libraries are designed to work independently. + +Refer to the following table to know which dependencies are required for each Readium library. + +| | `R2Shared` | `R2Streamer` | `R2Navigator` | `ReadiumOPDS` | `ReadiumLCP` | +|-----------------|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:| +| **`R2Shared`** | | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| `CryptoSwift` | | :heavy_check_mark: | | | :heavy_check_mark: | +| `DifferenceKit` | | | :heavy_check_mark: | | | +| `Fuzi` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| `GCDWebServer` | | :heavy_check_mark: | | | | +| `Minizip` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| `SQLite.swift` | | | | | :heavy_check_mark: | +| `SwiftSoup` | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| `ZIPFoundation` | | | | | :heavy_check_mark: | + +### CocoaPods + +Add the following `pod` statements to your `Podfile` for the Readium libraries you want to use: + +``` +pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumShared.podspec' +pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumStreamer.podspec' +pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumNavigator.podspec' +pod 'ReadiumOPDS', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumOPDS.podspec' +pod 'ReadiumLCP', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumLCP.podspec' +``` + +Take a look at [CocoaPods's documentation](https://guides.cocoapods.org/using/using-cocoapods.html) 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: + +```sh +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](mailto:contact@edrlab.org) to request your private `R2LCPClient.framework` and the setup instructions. diff --git a/Sources/LCP/readium-lcp-swift.h b/Sources/LCP/readium-lcp-swift.h deleted file mode 100644 index 23fd18913..000000000 --- a/Sources/LCP/readium-lcp-swift.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// readium-lcp-swift.h -// readium-lcp-swift -// -// Created by Alexandre Camilleri on 9/11/17. -// -// Copyright 2018 Readium Foundation. All rights reserved. -// Use of this source code is governed by a BSD-style license which is detailed -// in the LICENSE file present in the project repository where this source code is maintained. -// - -#import - -//! Project version number for readium-lcp-swift. -FOUNDATION_EXPORT double readium_lcp_swiftVersionNumber; - -//! Project version string for readium-lcp-swift. -FOUNDATION_EXPORT const unsigned char readium_lcp_swiftVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/Sources/Navigator/r2-navigator-swift.h b/Sources/Navigator/r2-navigator-swift.h deleted file mode 100644 index bde3b3965..000000000 --- a/Sources/Navigator/r2-navigator-swift.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// r2-navigator-swift.h -// r2-navigator-swift -// -// Created by Alexandre Camilleri on 8/23/17. -// -// Copyright 2018 Readium Foundation. All rights reserved. -// Use of this source code is governed by a BSD-style license which is detailed -// in the LICENSE file present in the project repository where this source code is maintained. -// - -#import - -//! Project version number for r2-navigator-swift. -FOUNDATION_EXPORT double r2_navigator_swiftVersionNumber; - -//! Project version string for r2-navigator-swift. -FOUNDATION_EXPORT const unsigned char r2_navigator_swiftVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/Sources/OPDS/readium_opds.h b/Sources/OPDS/readium_opds.h deleted file mode 100644 index d0290e1b0..000000000 --- a/Sources/OPDS/readium_opds.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// readium_opds.h -// readium-opds -// -// Created by Alexandre Camilleri on 10/27/17. -// -// Copyright 2018 Readium Foundation. All rights reserved. -// Use of this source code is governed by a BSD-style license which is detailed -// in the LICENSE file present in the project repository where this source code is maintained. -// - -#import - -//! Project version number for readium_opds. -FOUNDATION_EXPORT double readium_opdsVersionNumber; - -//! Project version string for readium_opds. -FOUNDATION_EXPORT const unsigned char readium_opdsVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/Sources/Shared/r2-shared-swift.h b/Sources/Shared/r2-shared-swift.h deleted file mode 100644 index 22fe44c21..000000000 --- a/Sources/Shared/r2-shared-swift.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// r2-shared-swift.h -// r2-shared-swift -// -// Created by Alexandre Camilleri on 8/24/17. -// -// Copyright 2018 Readium Foundation. All rights reserved. -// Use of this source code is governed by a BSD-style license which is detailed -// in the LICENSE file present in the project repository where this source code is maintained. -// - -#import - -//! Project version number for r2-shared-swift. -FOUNDATION_EXPORT double r2_shared_swiftVersionNumber; - -//! Project version string for r2-shared-swift. -FOUNDATION_EXPORT const unsigned char r2_shared_swiftVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/Sources/Streamer/r2-streamer-swift-Bridging-Header.h b/Sources/Streamer/r2-streamer-swift-Bridging-Header.h deleted file mode 100644 index ec5411a14..000000000 --- a/Sources/Streamer/r2-streamer-swift-Bridging-Header.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// r2-streamer-swift-Bridging-Header.h -// r2-streamer-swift -// -// Created by Olivier Körner on 21/12/2016. -// -// Copyright 2018 Readium Foundation. All rights reserved. -// Use of this source code is governed by a BSD-style license which is detailed -// in the LICENSE file present in the project repository where this source code is maintained. -// - -#ifndef R2Streamer_Bridging_Header_h -#define R2Streamer_Bridging_Header_h - -#import -#import - -#endif /* R2Streamer_Bridging_Header_h */ diff --git a/Sources/Streamer/r2-streamer-swift.h b/Sources/Streamer/r2-streamer-swift.h deleted file mode 100644 index 2791e541c..000000000 --- a/Sources/Streamer/r2-streamer-swift.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// r2-streamer-swift.h -// r2-streamer-swift -// -// Created by Olivier Körner on 18/01/2017. -// -// Copyright 2018 Readium Foundation. All rights reserved. -// Use of this source code is governed by a BSD-style license which is detailed -// in the LICENSE file present in the project repository where this source code is maintained. -// - -#import - -//! Project version number for R2Streamer. -FOUNDATION_EXPORT double R2StreamerVersionNumber; - -//! Project version string for R2Streamer. -FOUNDATION_EXPORT const unsigned char R2StreamerVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/PM/Carthage/.xcodegen b/Support/Carthage/.xcodegen similarity index 99% rename from PM/Carthage/.xcodegen rename to Support/Carthage/.xcodegen index 686b1f2f5..ab6266fb3 100644 --- a/PM/Carthage/.xcodegen +++ b/Support/Carthage/.xcodegen @@ -268,7 +268,6 @@ ../../Sources/LCP/Persistence/Database.swift ../../Sources/LCP/Persistence/Licenses.swift ../../Sources/LCP/Persistence/Transactions.swift -../../Sources/LCP/readium-lcp-swift.h ../../Sources/LCP/Resources ../../Sources/LCP/Resources/en.lproj ../../Sources/LCP/Resources/en.lproj/Localizable.strings @@ -7390,7 +7389,6 @@ ../../Sources/Navigator/PDF/PDFDocumentView.swift ../../Sources/Navigator/PDF/PDFNavigatorViewController.swift ../../Sources/Navigator/PDF/PDFTapGestureController.swift -../../Sources/Navigator/r2-navigator-swift.h ../../Sources/Navigator/Resources ../../Sources/Navigator/Resources/en.lproj ../../Sources/Navigator/Resources/en.lproj/Localizable.strings @@ -7414,7 +7412,6 @@ ../../Sources/OPDS/OPDS2Parser.swift ../../Sources/OPDS/OPDSParser.swift ../../Sources/OPDS/ParseData.swift -../../Sources/OPDS/readium_opds.h ../../Sources/OPDS/URLHelper.swift ../../Sources/Shared ../../Sources/Shared/DRM @@ -7516,7 +7513,6 @@ ../../Sources/Shared/Publication/User Settings ../../Sources/Shared/Publication/User Settings/UserProperties.swift ../../Sources/Shared/Publication/User Settings/UserSettings.swift -../../Sources/Shared/r2-shared-swift.h ../../Sources/Shared/Resources ../../Sources/Shared/Resources/en.lproj ../../Sources/Shared/Resources/en.lproj/Localizable.strings @@ -7623,8 +7619,6 @@ ../../Sources/Streamer/Parser/PublicationParser.swift ../../Sources/Streamer/Parser/Readium ../../Sources/Streamer/Parser/Readium/ReadiumWebPubParser.swift -../../Sources/Streamer/r2-streamer-swift-Bridging-Header.h -../../Sources/Streamer/r2-streamer-swift.h ../../Sources/Streamer/Server ../../Sources/Streamer/Server/PublicationServer.swift ../../Sources/Streamer/Server/WebServerResourceResponse.swift diff --git a/PM/Carthage/Info.plist b/Support/Carthage/Info.plist similarity index 100% rename from PM/Carthage/Info.plist rename to Support/Carthage/Info.plist diff --git a/PM/Carthage/Readium.xcodeproj/project.pbxproj b/Support/Carthage/Readium.xcodeproj/project.pbxproj similarity index 97% rename from PM/Carthage/Readium.xcodeproj/project.pbxproj rename to Support/Carthage/Readium.xcodeproj/project.pbxproj index 0369cd152..69e9dd288 100644 --- a/PM/Carthage/Readium.xcodeproj/project.pbxproj +++ b/Support/Carthage/Readium.xcodeproj/project.pbxproj @@ -72,20 +72,17 @@ 34A05B3E26E23B63B5081137 /* ZIPArchive.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA10E1438AE5AF459033776A /* ZIPArchive.swift */; }; 37304FB79C9ADE733248EA24 /* ResourceInputStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E5D8A1F865EDF9A7DAD31D /* ResourceInputStream.swift */; }; 37D9B0A6B141DDF2FD618B09 /* MediaTypeSnifferContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300E15AA6D30BBFB7416AC01 /* MediaTypeSnifferContext.swift */; }; - 37DBEBD3F7E2B7BA88147F7A /* r2-shared-swift.h in Headers */ = {isa = PBXBuildFile; fileRef = 261932356E0E3BFC9A79B903 /* r2-shared-swift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3899566CA6D41A6D5E495B0B /* FailureResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4BE7189EAC1F2DBE7054606 /* FailureResource.swift */; }; 39FC65D3797EF5069A04F34B /* HTTPFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 049EDB4F925E0AFEDA7318A5 /* HTTPFetcher.swift */; }; 3AA4BD1DA87C0952E4E4DD53 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE7B762C97CFC214997EC677 /* Weak.swift */; }; 3AA922C55CF12B575F5CC9FB /* Properties+Presentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C2787EBE9D5565DA8593711 /* Properties+Presentation.swift */; }; 3B1820FD0226743B1DE41FCF /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90AE9BB78C8A3FA5708F6AE6 /* Resource.swift */; }; - 3B5BDD557EC7654E3127B9A5 /* r2-streamer-swift.h in Headers */ = {isa = PBXBuildFile; fileRef = 32C8D72788D924BA3352B5D7 /* r2-streamer-swift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3D40B96F2D82B05CBB5F4924 /* Fetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = D81A35A8B299AD4B74915291 /* Fetcher.swift */; }; 3D9CB0E9FD88A14EEF9D7F2A /* ExplodedArchive.swift in Sources */ = {isa = PBXBuildFile; fileRef = C59803AADFCF32C93C9D9D29 /* ExplodedArchive.swift */; }; 3E7614CCBAD233B2D90BF5DC /* PDFPositionsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2A38D366CE8560BCBAC8B /* PDFPositionsService.swift */; }; 3ED6D98B993DB299CFB0513A /* Seekable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37141BCDFDB6BDBB58CDDD8 /* Seekable.swift */; }; 41D9812679A98F44DA9E7BFD /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E788FD34BE635B4B80C18A6 /* UIColor.swift */; }; 4203767BBAACC7B330623F62 /* Cancellable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD54FD376456C1925316BC /* Cancellable.swift */; }; - 43B170058CD5B96FEC9A57A5 /* readium-lcp-swift.h in Headers */ = {isa = PBXBuildFile; fileRef = B8FBC511B001099C63C474E2 /* readium-lcp-swift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 44152DBECE34F063AD0E93BC /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE3E6442F0C7FE2098D71F27 /* Link.swift */; }; 4542CC5374B86D81C4AD0F88 /* PDFDocumentHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6AD227BF7C477BF13B0BB94 /* PDFDocumentHolder.swift */; }; 46840B03E1F84B00E355CA39 /* NavigationDocumentParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29AD63CD2A41586290547212 /* NavigationDocumentParser.swift */; }; @@ -119,7 +116,6 @@ 5A40B83CF103A9102DF233E2 /* LoggerStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72922E22040CEFB3B7BBCDAF /* LoggerStub.swift */; }; 5B166084DFB7FF0DFD1D111B /* OPDSPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C22408FE1FA81400DE8D5F7 /* OPDSPrice.swift */; }; 5B38F9D78BD04D7385E4B3E4 /* UserRights.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C115FF0939F69AD83AE82 /* UserRights.swift */; }; - 5B828FFDE3AC9243EC8F1B90 /* r2-navigator-swift.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D8FE93E1060D9FAB02557E /* r2-navigator-swift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5BF07D73985075F71E70F5D3 /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1225F795A69CCB10692A56B5 /* Deprecated.swift */; }; 5C051B93B795D76666F4344B /* Metadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01B24895126F2A744A8E9E61 /* Metadata.swift */; }; 5C8ED4151A6C7EF6608A03F8 /* AudioSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ECD1D0BE2C4BB5B58E32BFD /* AudioSession.swift */; }; @@ -144,7 +140,6 @@ 70E5D945A0B0BBC84F64C173 /* PDFTapGestureController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF324AD5E3E30687AC5262D /* PDFTapGestureController.swift */; }; 718323B1A0C981D1B7A08F91 /* TransformingResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6CA450B17BF2F7FDFA4471C /* TransformingResource.swift */; }; 72783496FFF2387D3666FB88 /* DifferenceKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F95F3F20D758BE0E7005EA3 /* DifferenceKit.xcframework */; }; - 72DB80E4595DD0935F7BE9E7 /* r2-streamer-swift-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = DE273286DE9B42C181BFC459 /* r2-streamer-swift-Bridging-Header.h */; settings = {ATTRIBUTES = (Public, ); }; }; 75044A4E2B2011D9DE749847 /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 600D8714B762FE37DE405C2E /* LocalizedString.swift */; }; 76B36679FD740158FD9C5DCB /* FileAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 691C96D23D42A0C6AC03B1AE /* FileAsset.swift */; }; 788C81F1A7B4EED1DB46762C /* EPUBHTMLInjector.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8D12E849DAD3C5EF46D3BE5 /* EPUBHTMLInjector.swift */; }; @@ -186,7 +181,6 @@ 98428BC24846D534B940CE86 /* CryptoSwift.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = E37F94C388A86CB8A34812A5 /* CryptoSwift.xcframework */; }; 98702AFB56F9C50F7246CDDA /* LCPError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A115134AA0B8F5254C8139 /* LCPError.swift */; }; 98ABD996FB77EDF7DA69B18F /* DiffableDecoration+HTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01265194649A8E2A821CC2A4 /* DiffableDecoration+HTML.swift */; }; - 99A24C9A47F94F905B35D533 /* readium_opds.h in Headers */ = {isa = PBXBuildFile; fileRef = ADF2E5511DA717BD7E53CA9E /* readium_opds.h */; settings = {ATTRIBUTES = (Public, ); }; }; 99F3C8988EA41B0376D85F72 /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEE6DBDF8E3D1ABE990DB33 /* Bundle.swift */; }; 9A22C456F6A73F29AD9B0CE8 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11252900E9B0827C0FD2FA4B /* Database.swift */; }; 9A993922691ACA961F3B16A7 /* DataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2C9762191DAD823E7C925A5 /* DataExtension.swift */; }; @@ -369,8 +363,6 @@ 239A56BB0E6DAF17E0A13447 /* CBZNavigatorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBZNavigatorViewController.swift; sourceTree = ""; }; 251275D0DF87F85158A5FEA9 /* Assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Assets; path = ../../Sources/Navigator/EPUB/Assets; sourceTree = SOURCE_ROOT; }; 25FD89B99234B85BD2A8FC3E /* MediaNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaNavigator.swift; sourceTree = ""; }; - 261932356E0E3BFC9A79B903 /* r2-shared-swift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "r2-shared-swift.h"; sourceTree = ""; }; - 26D8FE93E1060D9FAB02557E /* r2-navigator-swift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "r2-navigator-swift.h"; sourceTree = ""; }; 27E446AE5B40C2C4E5531536 /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = ""; }; 294E01A2E6FF25539EBC1082 /* Properties+Archive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Properties+Archive.swift"; sourceTree = ""; }; 29AD63CD2A41586290547212 /* NavigationDocumentParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationDocumentParser.swift; sourceTree = ""; }; @@ -382,7 +374,6 @@ 2DE48021CF3FED1C3340E458 /* RoutingFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoutingFetcher.swift; sourceTree = ""; }; 2DF03272C07D6951ADC1311E /* Publication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Publication.swift; sourceTree = ""; }; 300E15AA6D30BBFB7416AC01 /* MediaTypeSnifferContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaTypeSnifferContext.swift; sourceTree = ""; }; - 32C8D72788D924BA3352B5D7 /* r2-streamer-swift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "r2-streamer-swift.h"; sourceTree = ""; }; 339637CCF01E665F4CB78B01 /* EPUBLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EPUBLayout.swift; sourceTree = ""; }; 33C422C1CFB72372FC343AE4 /* ContentProtectionService+WS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ContentProtectionService+WS.swift"; sourceTree = ""; }; 33FD18E1CF87271DA6A6A783 /* Connection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Connection.swift; sourceTree = ""; }; @@ -519,7 +510,6 @@ ABAF1D0444B94E2CDD80087D /* PDFKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PDFKit.swift; sourceTree = ""; }; ACB32E55E1F3CAF1737979CC /* DataCompression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataCompression.swift; sourceTree = ""; }; ADDB8B9906FC78C038203BDD /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; - ADF2E5511DA717BD7E53CA9E /* readium_opds.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = readium_opds.h; sourceTree = ""; }; AE0F9F65A46A9D2B4AF1A0FE /* BufferedResource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BufferedResource.swift; sourceTree = ""; }; B0276C0D645E8013EE0F86FA /* ZIPInputStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZIPInputStream.swift; sourceTree = ""; }; B1085F2D690A73984E675D54 /* ParseData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseData.swift; sourceTree = ""; }; @@ -528,7 +518,6 @@ B421601FB56132514CCD9699 /* Fuzi.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Fuzi.xcframework; path = ../../Carthage/Build/Fuzi.xcframework; sourceTree = ""; }; B5CE464C519852D38F873ADB /* PotentialRights.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PotentialRights.swift; sourceTree = ""; }; B7C9D54352714641A87F64A0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; - B8FBC511B001099C63C474E2 /* readium-lcp-swift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "readium-lcp-swift.h"; sourceTree = ""; }; BB11EA964FBB42D44C3E4A50 /* StringEncoding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringEncoding.swift; sourceTree = ""; }; BC45956B8991A9488F957B06 /* PositionsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionsService.swift; sourceTree = ""; }; BCF859D4933121BDC376CC8A /* Event.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = ""; }; @@ -568,7 +557,6 @@ D9FFEB1FF4B5CD74EB35CD63 /* AudioParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioParser.swift; sourceTree = ""; }; DBCE9786DD346E6BDB2E50FF /* Assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Assets; path = ../../Sources/Streamer/Assets; sourceTree = SOURCE_ROOT; }; DCE34D74E282834684E1C999 /* AudioNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioNavigator.swift; sourceTree = ""; }; - DE273286DE9B42C181BFC459 /* r2-streamer-swift-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "r2-streamer-swift-Bridging-Header.h"; sourceTree = ""; }; DF89316F77F23DACA2E04696 /* PDFDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PDFDocument.swift; sourceTree = ""; }; DF92954C8C8C3EC50C835CBA /* Link.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Link.swift; sourceTree = ""; }; E0136BC8AC2E0F3171763FEB /* R2NavigatorLocalizedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = R2NavigatorLocalizedString.swift; sourceTree = ""; }; @@ -773,7 +761,6 @@ 1C708ABF037ECFAF5BFE72F5 /* Shared */ = { isa = PBXGroup; children = ( - 261932356E0E3BFC9A79B903 /* r2-shared-swift.h */, 01A72947C91934D96A7EAA23 /* RootFile.swift */, ACF678E2BE7B4761BD204AA7 /* DRM */, ECD3E07CBAEDA1F36EFA7842 /* Fetcher */, @@ -1057,7 +1044,6 @@ 9935832F8ECA0AB7A7A486FC /* OPDS2Parser.swift */, 07B5469E40752E598C070E5B /* OPDSParser.swift */, B1085F2D690A73984E675D54 /* ParseData.swift */, - ADF2E5511DA717BD7E53CA9E /* readium_opds.h */, E19D31097B3A8050A46CDAA5 /* URLHelper.swift */, ); name = OPDS; @@ -1369,7 +1355,6 @@ 093629E752DE17264B97C598 /* LCPLicense.swift */, 230985A228FA74F24735D6BB /* LCPRenewDelegate.swift */, 67DEBFCD9D71243C4ACC3A49 /* LCPService.swift */, - B8FBC511B001099C63C474E2 /* readium-lcp-swift.h */, 7F42F058A2DC364B554BF7F2 /* Authentications */, F9064CEF2968AEDCDCCFD399 /* Content Protection */, 2C4C6FBF69B19C83DFCCF835 /* License */, @@ -1388,7 +1373,6 @@ F5C6D0C5860E802EDA23068C /* EditingAction.swift */, 25FD89B99234B85BD2A8FC3E /* MediaNavigator.swift */, 2BD6F93E379D0DC6FA1DCDEE /* Navigator.swift */, - 26D8FE93E1060D9FAB02557E /* r2-navigator-swift.h */, 4567A7ABB678715C37661DE3 /* SelectableNavigator.swift */, A94DA04D56753CC008F65B1A /* VisualNavigator.swift */, E51C5679EBD721E9AFACFE2A /* Audiobook */, @@ -1531,8 +1515,6 @@ F6157A0611A8122BC25855A1 /* Streamer */ = { isa = PBXGroup; children = ( - DE273286DE9B42C181BFC459 /* r2-streamer-swift-Bridging-Header.h */, - 32C8D72788D924BA3352B5D7 /* r2-streamer-swift.h */, FE961CB4827D937CE3862B51 /* Streamer.swift */, C9162673C4ED48734447823A /* Model */, C6D767E6D0B9374779FD7D84 /* Parser */, @@ -1591,45 +1573,11 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 415E457329F1810839DA5235 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 37DBEBD3F7E2B7BA88147F7A /* r2-shared-swift.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 6CD207EA5BC77D5FC1E67BE3 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 108D833B59AF7643DB45D867 /* Zip.h in Headers */, - 72DB80E4595DD0935F7BE9E7 /* r2-streamer-swift-Bridging-Header.h in Headers */, - 3B5BDD557EC7654E3127B9A5 /* r2-streamer-swift.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 734BB9EB5972C80CDF626677 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 99A24C9A47F94F905B35D533 /* readium_opds.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B31451B2CD40F18E308E5925 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 43B170058CD5B96FEC9A57A5 /* readium-lcp-swift.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B83CCE48A93725A05196DD36 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 5B828FFDE3AC9243EC8F1B90 /* r2-navigator-swift.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1659,7 +1607,6 @@ isa = PBXNativeTarget; buildConfigurationList = 501C4C36DD8FD715F514D176 /* Build configuration list for PBXNativeTarget "ReadiumLCP" */; buildPhases = ( - B31451B2CD40F18E308E5925 /* Headers */, C838BE0B99F9BE98533BD189 /* Sources */, 3730713519F0AF3F9C5A58A1 /* Resources */, 1D30962BE469B43E9601FAEA /* Frameworks */, @@ -1678,7 +1625,6 @@ isa = PBXNativeTarget; buildConfigurationList = 3F2668BE4ABB5994C0B5A1B2 /* Build configuration list for PBXNativeTarget "R2Shared" */; buildPhases = ( - 415E457329F1810839DA5235 /* Headers */, B00EB5FC54F3B7973245BA55 /* Sources */, F9F8CB7FB2C3285C4E84A277 /* Resources */, 88717AEF1BEFA94ACFD5D894 /* Frameworks */, @@ -1696,7 +1642,6 @@ isa = PBXNativeTarget; buildConfigurationList = 9569C3F5C334DCA235C0A178 /* Build configuration list for PBXNativeTarget "R2Navigator" */; buildPhases = ( - B83CCE48A93725A05196DD36 /* Headers */, A12F3279CAF7547509614CEC /* Sources */, 5DA4F1E3DBC7B26E85D80978 /* Resources */, 9E41E41E6EAC80FFB5A55069 /* Frameworks */, @@ -1715,7 +1660,6 @@ isa = PBXNativeTarget; buildConfigurationList = CABDEA95B2658ADADF446805 /* Build configuration list for PBXNativeTarget "ReadiumOPDS" */; buildPhases = ( - 734BB9EB5972C80CDF626677 /* Headers */, E9DA95D8616435BA1647E9A3 /* Sources */, D16C6C1E80D545D5310B16AB /* Frameworks */, ); diff --git a/PM/Carthage/Readium.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Support/Carthage/Readium.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from PM/Carthage/Readium.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Support/Carthage/Readium.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/PM/Carthage/Readium.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Support/Carthage/Readium.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from PM/Carthage/Readium.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to Support/Carthage/Readium.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Navigator.xcscheme b/Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Navigator.xcscheme similarity index 100% rename from PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Navigator.xcscheme rename to Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Navigator.xcscheme diff --git a/PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Shared.xcscheme b/Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Shared.xcscheme similarity index 100% rename from PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Shared.xcscheme rename to Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Shared.xcscheme diff --git a/PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Streamer.xcscheme b/Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Streamer.xcscheme similarity index 100% rename from PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Streamer.xcscheme rename to Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/R2Streamer.xcscheme diff --git a/PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumLCP.xcscheme b/Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumLCP.xcscheme similarity index 100% rename from PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumLCP.xcscheme rename to Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumLCP.xcscheme diff --git a/PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumOPDS.xcscheme b/Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumOPDS.xcscheme similarity index 100% rename from PM/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumOPDS.xcscheme rename to Support/Carthage/Readium.xcodeproj/xcshareddata/xcschemes/ReadiumOPDS.xcscheme diff --git a/PM/Carthage/project-as-submodule.yml b/Support/Carthage/project-as-submodule.yml similarity index 100% rename from PM/Carthage/project-as-submodule.yml rename to Support/Carthage/project-as-submodule.yml diff --git a/PM/Carthage/project.yml b/Support/Carthage/project.yml similarity index 100% rename from PM/Carthage/project.yml rename to Support/Carthage/project.yml diff --git a/PM/CocoaPods/ReadiumLCP.podspec b/Support/CocoaPods/ReadiumLCP.podspec similarity index 100% rename from PM/CocoaPods/ReadiumLCP.podspec rename to Support/CocoaPods/ReadiumLCP.podspec diff --git a/PM/CocoaPods/ReadiumNavigator.podspec b/Support/CocoaPods/ReadiumNavigator.podspec similarity index 100% rename from PM/CocoaPods/ReadiumNavigator.podspec rename to Support/CocoaPods/ReadiumNavigator.podspec diff --git a/PM/CocoaPods/ReadiumOPDS.podspec b/Support/CocoaPods/ReadiumOPDS.podspec similarity index 100% rename from PM/CocoaPods/ReadiumOPDS.podspec rename to Support/CocoaPods/ReadiumOPDS.podspec diff --git a/PM/CocoaPods/ReadiumShared.podspec b/Support/CocoaPods/ReadiumShared.podspec similarity index 100% rename from PM/CocoaPods/ReadiumShared.podspec rename to Support/CocoaPods/ReadiumShared.podspec diff --git a/PM/CocoaPods/ReadiumStreamer.podspec b/Support/CocoaPods/ReadiumStreamer.podspec similarity index 100% rename from PM/CocoaPods/ReadiumStreamer.podspec rename to Support/CocoaPods/ReadiumStreamer.podspec diff --git a/TestApp/Integrations/CocoaPods/Podfile b/TestApp/Integrations/CocoaPods/Podfile index 178f7487c..5c46e19e7 100644 --- a/TestApp/Integrations/CocoaPods/Podfile +++ b/TestApp/Integrations/CocoaPods/Podfile @@ -4,10 +4,10 @@ target 'TestApp' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! - pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/PM/CocoaPods/ReadiumShared.podspec' - pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/PM/CocoaPods/ReadiumStreamer.podspec' - pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/PM/CocoaPods/ReadiumNavigator.podspec' - pod 'ReadiumOPDS', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/PM/CocoaPods/ReadiumOPDS.podspec' + pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/Support/CocoaPods/ReadiumShared.podspec' + pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/Support/CocoaPods/ReadiumStreamer.podspec' + pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/Support/CocoaPods/ReadiumNavigator.podspec' + pod 'ReadiumOPDS', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/Support/CocoaPods/ReadiumOPDS.podspec' pod 'GCDWebServer', podspec: 'https://raw.githubusercontent.com/readium/GCDWebServer/3.6.3/GCDWebServer.podspec' pod 'GRDB.swift' diff --git a/TestApp/Integrations/CocoaPods/Podfile+lcp b/TestApp/Integrations/CocoaPods/Podfile+lcp index 85d2b654a..7a3d09918 100644 --- a/TestApp/Integrations/CocoaPods/Podfile+lcp +++ b/TestApp/Integrations/CocoaPods/Podfile+lcp @@ -4,11 +4,11 @@ target 'TestApp' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! - pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/PM/CocoaPods/ReadiumShared.podspec' - pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/PM/CocoaPods/ReadiumStreamer.podspec' - pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/PM/CocoaPods/ReadiumNavigator.podspec' - pod 'ReadiumOPDS', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/PM/CocoaPods/ReadiumOPDS.podspec' - pod 'ReadiumLCP', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/PM/CocoaPods/ReadiumLCP.podspec' + pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/Support/CocoaPods/ReadiumShared.podspec' + pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/Support/CocoaPods/ReadiumStreamer.podspec' + pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/Support/CocoaPods/ReadiumNavigator.podspec' + pod 'ReadiumOPDS', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/Support/CocoaPods/ReadiumOPDS.podspec' + pod 'ReadiumLCP', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/VERSION/Support/CocoaPods/ReadiumLCP.podspec' pod 'R2LCPClient', podspec: 'LCP_URL' pod 'GCDWebServer', podspec: 'https://raw.githubusercontent.com/readium/GCDWebServer/3.6.3/GCDWebServer.podspec' diff --git a/TestApp/README.md b/TestApp/README.md index 2f5b1cab5..fcfdfda02 100644 --- a/TestApp/README.md +++ b/TestApp/README.md @@ -1,11 +1,9 @@ -# Readium Mobile Test App (Swift/iOS) +# Readium Test App (Swift/iOS) -[![BSD-3](https://img.shields.io/badge/License-BSD--3-brightgreen.svg)](https://opensource.org/licenses/BSD-3-Clause) +This sample application demonstrates how to integrate the Readium Swift toolkit in your own reading app. Stable versions are [published on TestFlight](https://testflight.apple.com/join/lYEMEfBr). -This sample application demonstrates how to integrate the Readium 2 Swift toolkit in your own reading app. Stable versions are [published on TestFlight](https://testflight.apple.com/join/lYEMEfBr). - ---- +
@@ -14,71 +12,48 @@ This sample application demonstrates how to integrate the Readium 2 Swift toolki ## Features -- [x] EPUB 2.x and 3.x support -- [x] Readium LCP support -- [x] CBZ support -- [x] Custom styles -- [x] Night & sepia modes -- [x] Pagination and scrolling -- [x] Table of contents -- [x] OPDS 1.x and 2.0 support -- [x] EPUB fixed layout support -- [x] Right-to-left support +* Supported publication formats: + * EPUB 2 and 3 (reflowable and fixed layout) + * Custom styles + * Night & sepia modes + * CBZ + * PDF +* Readium LCP support +* Pagination and scrolling +* Table of contents +* OPDS 1.x and 2.0 support +* Right-to-left support ## Building the Test App -This project shows how to use Readium 2 with several dependency managers: Swift Package Manager, Carthage and CocoaPods. To simplify the setup, we use [XcodeGen](https://github.com/yonaskolb/XcodeGen) to automatically generate the Xcode project files for a given dependency manager. +This project shows how to use Readium with several dependency managers: Swift Package Manager, Carthage and CocoaPods. To simplify the setup, we use [XcodeGen](https://github.com/yonaskolb/XcodeGen) to automatically generate the Xcode project files for a given dependency manager. -1. Choose a type of project to generate: +1. Install [XcodeGen](https://github.com/yonaskolb/XcodeGen) and the dependency manager you need. +2. Clone the project. + ```sh + git clone https://github.com/readium/swift-toolkit.git + cd swift-toolkit/TestApp + ``` +3. Choose a type of project to generate: * `spm` for Swift Package Manager (recommended) * `carthage` for Carthage * `cocoapods` for CocoaPods * `dev` for Git submodules with Swift Package Manager -2. Install [XcodeGen](https://github.com/yonaskolb/XcodeGen) and the dependency manager you need. -3. Clone the project. - ```sh - git clone https://github.com/readium/r2-testapp-swift.git - cd r2-testapp-swift - ``` -4. Generate the Xcode project using our `Makefile` and your target of choice. This will download all dependencies automatically. +4. Generate the Xcode project using the `Makefile` and your target of choice. This will download all the dependencies automatically. ```sh make spm ``` -**Warning:** Since the Xcode project is not committed to this repository, you need to run the `make ` command again after pulling any change from `r2-testapp-swift`. + +:warning: Since the Xcode project is not committed to this repository, you need to run the `make ` command again after pulling any change from `r2-testapp-swift`. ### Building with Readium LCP -Building with Readium LCP requires additional dependencies, including the binary `R2LCPClient.framework` provided by EDRLab. +Building with Readium LCP requires additional dependencies, including the library `R2LCPClient.framework` provided by EDRLab. 1. [Contact EDRLab](mailto:contact@edrlab.org) to request your private `R2LCPClient.framework`. -2. If you integrate Readium 2 with Swift Package Manager or Git submodules, install [Carthage](https://github.com/Carthage/Carthage). `R2LCPClient.framework` is only available for Carthage or CocoaPods. +2. If you integrate Readium with Swift Package Manager or Git submodules, install [Carthage](https://github.com/Carthage/Carthage). `R2LCPClient.framework` is only available for Carthage or CocoaPods. 3. Generate the Xcode project with `make`, providing the URL given by EDRLab as the `url` parameter (`.json` for Carthage or SPM and `.podspec` for CocoaPods). ```sh make spm lcp=https://...json ``` -## Integrating Readium 2 in your app - -All migration steps necessary in reading apps to upgrade to major versions of the Readium toolkit are documented in the [migration guide](https://readium.org/mobile/swift/migration-guide). - -The Readium 2 toolkit is split in several independent modules, following the [Readium Architecture](https://github.com/readium/architecture): - -* [`r2-shared-swift`](https://github.com/readium/r2-shared-swift) – Shared `Publication` models and utilities -* [`r2-streamer-swift`](https://github.com/readium/r2-streamer-swift) – Publication parsers and local HTTP server -* [`r2-navigator-swift`](https://github.com/readium/r2-navigator-swift) – Plain view controllers rendering publications -* [`r2-opds-swift`](https://github.com/readium/r2-opds-swift) – Parsers for OPDS catalog feeds -* [`r2-lcp-swift`](https://github.com/readium/r2-lcp-swift) – Service and models for Readium LCP -* [`readium-css`](https://github.com/readium/readium-css) – CSS styles for EPUB publications - -To understand how to integrate these dependencies in your project, take a look at the Xcode project created by `XcodeGen`. Or even better, check out the generated `project.yml` file which describes the structure of the Xcode project in a human-friendly way. - -## Contributing - -Follow the project on [ZenHub](https://app.zenhub.com/workspace/o/readium/r2-testapp-swift/boards). - -The easiest way to contribute to the Readium 2 modules is to use the Git submodules integration. - -```sh -make dev -``` -