diff --git a/README.md b/README.md
index e29f8f563..78c761bbc 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@ If you're stuck, find more information at [developer.apple.com](https://develope
Add the following to your `Cartfile`:
```
-github "readium/swift-toolkit" ~> 3.0.0-beta.2
+github "readium/swift-toolkit" ~> 3.0.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.
@@ -74,11 +74,11 @@ Add the following `pod` statements to your `Podfile` for the Readium libraries y
source 'https://github.com/readium/podspecs'
source 'https://cdn.cocoapods.org/'
-pod 'ReadiumShared', '~> 3.0.0-beta.2'
-pod 'ReadiumStreamer', '~> 3.0.0-beta.2'
-pod 'ReadiumNavigator', '~> 3.0.0-beta.2'
-pod 'ReadiumOPDS', '~> 3.0.0-beta.2'
-pod 'ReadiumLCP', '~> 3.0.0-beta.2'
+pod 'ReadiumShared', '~> 3.0.0'
+pod 'ReadiumStreamer', '~> 3.0.0'
+pod 'ReadiumNavigator', '~> 3.0.0'
+pod 'ReadiumOPDS', '~> 3.0.0'
+pod 'ReadiumLCP', '~> 3.0.0'
```
Take a look at [CocoaPods's documentation](https://guides.cocoapods.org/using/using-cocoapods.html) for more information.
diff --git a/Support/CocoaPods/ReadiumAdapterGCDWebServer.podspec b/Support/CocoaPods/ReadiumAdapterGCDWebServer.podspec
index 300d2fb7d..982cfee16 100644
--- a/Support/CocoaPods/ReadiumAdapterGCDWebServer.podspec
+++ b/Support/CocoaPods/ReadiumAdapterGCDWebServer.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "ReadiumAdapterGCDWebServer"
- s.version = "3.0.0-beta.2"
+ s.version = "3.0.0"
s.license = "BSD 3-Clause License"
s.summary = "Adapter to use GCDWebServer as an HTTP server in Readium"
s.homepage = "http://readium.github.io"
@@ -14,8 +14,8 @@ Pod::Spec.new do |s|
s.ios.deployment_target = "13.4"
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
- s.dependency 'ReadiumShared', '~> 3.0.0-beta.2'
- s.dependency 'ReadiumInternal', '~> 3.0.0-beta.2'
+ s.dependency 'ReadiumShared', '~> 3.0.0'
+ s.dependency 'ReadiumInternal', '~> 3.0.0'
s.dependency 'ReadiumGCDWebServer', '~> 4.0.0'
end
diff --git a/Support/CocoaPods/ReadiumAdapterLCPSQLite.podspec b/Support/CocoaPods/ReadiumAdapterLCPSQLite.podspec
index a3188b168..6feca51d3 100644
--- a/Support/CocoaPods/ReadiumAdapterLCPSQLite.podspec
+++ b/Support/CocoaPods/ReadiumAdapterLCPSQLite.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "ReadiumAdapterLCPSQLite"
- s.version = "3.0.0-beta.2"
+ s.version = "3.0.0"
s.license = "BSD 3-Clause License"
s.summary = "Adapter to use SQLite.swift for the Readium LCP repositories"
s.homepage = "http://readium.github.io"
@@ -14,8 +14,8 @@ Pod::Spec.new do |s|
s.ios.deployment_target = "13.4"
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
- s.dependency 'ReadiumLCP', '~> 3.0.0-beta.2'
- s.dependency 'ReadiumShared', '~> 3.0.0-beta.2'
+ s.dependency 'ReadiumLCP', '~> 3.0.0'
+ s.dependency 'ReadiumShared', '~> 3.0.0'
s.dependency 'SQLite.swift', '~> 0.15.0'
end
diff --git a/Support/CocoaPods/ReadiumInternal.podspec b/Support/CocoaPods/ReadiumInternal.podspec
index e86ce3541..ea5f15ef5 100644
--- a/Support/CocoaPods/ReadiumInternal.podspec
+++ b/Support/CocoaPods/ReadiumInternal.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "ReadiumInternal"
- s.version = "3.0.0-beta.2"
+ s.version = "3.0.0"
s.license = "BSD 3-Clause License"
s.summary = "Private utilities used by the Readium modules"
s.homepage = "http://readium.github.io"
diff --git a/Support/CocoaPods/ReadiumLCP.podspec b/Support/CocoaPods/ReadiumLCP.podspec
index 509b8418c..114492fe0 100644
--- a/Support/CocoaPods/ReadiumLCP.podspec
+++ b/Support/CocoaPods/ReadiumLCP.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "ReadiumLCP"
- s.version = "3.0.0-beta.2"
+ s.version = "3.0.0"
s.license = "BSD 3-Clause License"
s.summary = "Readium LCP"
s.homepage = "http://readium.github.io"
@@ -20,8 +20,8 @@ Pod::Spec.new do |s|
s.ios.deployment_target = "13.4"
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2'}
- s.dependency 'ReadiumShared' , '~> 3.0.0-beta.2'
- s.dependency 'ReadiumInternal', '~> 3.0.0-beta.2'
+ s.dependency 'ReadiumShared' , '~> 3.0.0'
+ s.dependency 'ReadiumInternal', '~> 3.0.0'
s.dependency 'ReadiumZIPFoundation', '~> 1.0.0'
s.dependency 'CryptoSwift', '~> 1.8.0'
end
diff --git a/Support/CocoaPods/ReadiumNavigator.podspec b/Support/CocoaPods/ReadiumNavigator.podspec
index 05ac58e2e..644beafee 100644
--- a/Support/CocoaPods/ReadiumNavigator.podspec
+++ b/Support/CocoaPods/ReadiumNavigator.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "ReadiumNavigator"
- s.version = "3.0.0-beta.2"
+ s.version = "3.0.0"
s.license = "BSD 3-Clause License"
s.summary = "Readium Navigator"
s.homepage = "http://readium.github.io"
@@ -19,8 +19,8 @@ Pod::Spec.new do |s|
s.platform = :ios
s.ios.deployment_target = "13.4"
- s.dependency 'ReadiumShared', '~> 3.0.0-beta.2'
- s.dependency 'ReadiumInternal', '~> 3.0.0-beta.2'
+ s.dependency 'ReadiumShared', '~> 3.0.0'
+ s.dependency 'ReadiumInternal', '~> 3.0.0'
s.dependency 'DifferenceKit', '~> 1.0'
s.dependency 'SwiftSoup', '~> 2.7.0'
diff --git a/Support/CocoaPods/ReadiumOPDS.podspec b/Support/CocoaPods/ReadiumOPDS.podspec
index df13bafc5..ab3af0c7e 100644
--- a/Support/CocoaPods/ReadiumOPDS.podspec
+++ b/Support/CocoaPods/ReadiumOPDS.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "ReadiumOPDS"
- s.version = "3.0.0-beta.2"
+ s.version = "3.0.0"
s.license = "BSD 3-Clause License"
s.summary = "Readium OPDS"
s.homepage = "http://readium.github.io"
@@ -14,8 +14,8 @@ Pod::Spec.new do |s|
s.ios.deployment_target = "13.4"
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
- s.dependency 'ReadiumShared', '~> 3.0.0-beta.2'
- s.dependency 'ReadiumInternal', '~> 3.0.0-beta.2'
+ s.dependency 'ReadiumShared', '~> 3.0.0'
+ s.dependency 'ReadiumInternal', '~> 3.0.0'
s.dependency 'ReadiumFuzi', '~> 4.0.0'
end
diff --git a/Support/CocoaPods/ReadiumShared.podspec b/Support/CocoaPods/ReadiumShared.podspec
index 4b348b42f..62bccb111 100644
--- a/Support/CocoaPods/ReadiumShared.podspec
+++ b/Support/CocoaPods/ReadiumShared.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "ReadiumShared"
- s.version = "3.0.0-beta.2"
+ s.version = "3.0.0"
s.license = "BSD 3-Clause License"
s.summary = "Readium Shared"
s.homepage = "http://readium.github.io"
@@ -19,6 +19,6 @@ Pod::Spec.new do |s|
s.dependency 'SwiftSoup', '~> 2.7.0'
s.dependency 'ReadiumFuzi', '~> 4.0.0'
s.dependency 'ReadiumZIPFoundation', '~> 1.0.0'
- s.dependency 'ReadiumInternal', '~> 3.0.0-beta.2'
+ s.dependency 'ReadiumInternal', '~> 3.0.0'
end
diff --git a/Support/CocoaPods/ReadiumStreamer.podspec b/Support/CocoaPods/ReadiumStreamer.podspec
index 2e1db1a9e..b287d6fd9 100644
--- a/Support/CocoaPods/ReadiumStreamer.podspec
+++ b/Support/CocoaPods/ReadiumStreamer.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "ReadiumStreamer"
- s.version = "3.0.0-beta.2"
+ s.version = "3.0.0"
s.license = "BSD 3-Clause License"
s.summary = "Readium Streamer"
s.homepage = "http://readium.github.io"
@@ -22,8 +22,8 @@ Pod::Spec.new do |s|
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
s.dependency 'ReadiumFuzi', '~> 4.0.0'
- s.dependency 'ReadiumShared', '~> 3.0.0-beta.2'
- s.dependency 'ReadiumInternal', '~> 3.0.0-beta.2'
+ s.dependency 'ReadiumShared', '~> 3.0.0'
+ s.dependency 'ReadiumInternal', '~> 3.0.0'
s.dependency 'CryptoSwift', '~> 1.8.0'
end
diff --git a/TestApp/Integrations/Carthage/project+lcp.yml b/TestApp/Integrations/Carthage/project+lcp.yml
index a51ff0bdd..0e420dea4 100644
--- a/TestApp/Integrations/Carthage/project+lcp.yml
+++ b/TestApp/Integrations/Carthage/project+lcp.yml
@@ -28,6 +28,7 @@ targets:
- framework: Carthage/Build/R2LCPClient.xcframework
- framework: Carthage/Build/ReadiumAdapterGCDWebServer.xcframework
- framework: Carthage/Build/ReadiumAdapterLCPSQLite.xcframework
+ - framework: Carthage/Build/ReadiumFuzi.xcframework
- framework: Carthage/Build/ReadiumGCDWebServer.xcframework
- framework: Carthage/Build/ReadiumInternal.xcframework
- framework: Carthage/Build/ReadiumLCP.xcframework
diff --git a/TestApp/Sources/Info.plist b/TestApp/Sources/Info.plist
index 1a59c1145..b031736c6 100644
--- a/TestApp/Sources/Info.plist
+++ b/TestApp/Sources/Info.plist
@@ -252,9 +252,9 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 3.0.0-beta.2
+ 3.0.0
CFBundleVersion
- 3.0.0-beta.2
+ 3.0.0
LSRequiresIPhoneOS
LSSupportsOpeningDocumentsInPlace
diff --git a/docs/Migration Guide.md b/docs/Migration Guide.md
index 0d87c9c84..32b175aeb 100644
--- a/docs/Migration Guide.md
+++ b/docs/Migration Guide.md
@@ -4,9 +4,26 @@ All migration steps necessary in reading apps to upgrade to major versions of th
-## 3.0.0-beta.2
+## 3.0.0
-### CocoaPods Specs repository
+:warning: If you upgrade from an `alpha` or `beta` version of 3.0.0, please refer to the [3.0.0-beta.2 migration guide](https://github.com/readium/swift-toolkit/blob/3.0.0-beta.2/docs/Migration%20Guide.md) instead.
+
+### R2 prefix dropped
+
+The `R2` prefix is now deprecated. The `R2Shared`, `R2Streamer` and `R2Navigator` packages were renamed as `ReadiumShared`, `ReadiumStreamer` and `ReadiumNavigator`.
+
+You will need to update your imports, as well as the dependencies you include in your project:
+
+* Swift Package Manager: There's nothing to do.
+* Carthage:
+ * Update the Carthage dependencies and make sure the new `ReadiumShared.xcframework`, `ReadiumStreamer.xcframework` and `ReadiumNavigator.xcframework` were built.
+ * Replace the old frameworks with the new ones in your project.
+* CocoaPods:
+ * Update the `pod` statements to reflect the new names of `ReadiumShared`, `ReadiumStreamer` and `ReadiumNavigator`.
+
+### Dependency managers
+
+#### CocoaPods Specs repository
All the libraries are now available on a dedicated [Readium CocoaPods Specs repository](https://github.com/readium/podspecs). To use it, add the following statements at the top of your `Podfile`:
@@ -35,14 +52,57 @@ Don't forget to remove the statements for some internal dependencies that are no
Finally, run `pod install --repo-update`.
-### ZIPFoundation replaces Minizip
+#### ZIPFoundation replaces Minizip
The default `ZIPArchiveOpener` is now using ZIPFoundation instead of Minizip, with improved performances when reading ranges of `stored` ZIP entries.
If you use Carthage, remove `Minizip.xcframework` from your dependencies and add `ReadiumZIPFoundation.xcframework` instead. No changes are needed when using Swift Package Manager or CocoaPods.
+### Migration of HREFs and Locators (bookmarks, annotations, etc.)
-## 3.0.0-alpha.2
+ :warning: This requires a database migration in your application, if you were persisting `Locator` objects.
+
+ In Readium v2.x, a `Link` or `Locator`'s `href` could be either:
+
+ * a valid absolute URL for a streamed publication, e.g. `https://domain.com/isbn/dir/my%20chapter.html`,
+ * a percent-decoded path for a local archive such as an EPUB, e.g. `/dir/my chapter.html`.
+ * Note that it was relative to the root of the archive (`/`).
+
+ To improve the interoperability with other Readium toolkits (in particular the Readium Web Toolkits, which only work in a streaming context) **Readium v3 now generates and expects valid URLs** for `Locator` and `Link`'s `href`.
+
+ * `https://domain.com/isbn/dir/my%20chapter.html` is left unchanged, as it was already a valid URL.
+ * `/dir/my chapter.html` becomes the relative URL path `dir/my%20chapter.html`
+ * We dropped the `/` prefix to avoid issues when resolving to a base URL.
+ * Special characters are percent-encoded.
+
+ **You must migrate the HREFs or Locators stored in your database** when upgrading to Readium 3. To assist you, two helpers are provided: `AnyURL(legacyHREF:)` and `Locator(legacyJSONString:)`.
+
+ Here's an example of a [GRDB migration](https://swiftpackageindex.com/groue/grdb.swift/master/documentation/grdb/migrations) that can serve as inspiration:
+
+ ```swift
+ migrator.registerMigration("normalizeHREFs") { db in
+ let normalizedRows: [(id: Int, href: String, locator: String)] =
+ try Row.fetchAll(db, sql: "SELECT id, href, locator FROM bookmarks")
+ .compactMap { row in
+ guard
+ let normalizedHREF = AnyURL(legacyHREF: row["href"])?.string,
+ let normalizedLocator = try Locator(legacyJSONString: row["locator"])?.jsonString
+ else {
+ return nil
+ }
+ return (row["id"], normalizedHREF, normalizedLocator)
+ }
+
+ let updateStmt = try db.makeStatement(sql: "UPDATE bookmarks SET href = :href, locator = :locator WHERE id = :id")
+ for (id, href, locator) in normalizedRows {
+ try updateStmt.execute(arguments: [
+ "id": id,
+ "href": href
+ "locator": locator
+ ])
+ }
+}
+```
### Error management
@@ -119,7 +179,7 @@ To use `ReadiumAdapterLCPSQLite`, you must update your imports and the dependenc
* CocoaPods:
* Update the `pod` statements in your `Podfile` with the following, before running `pod install`:
```
- pod 'ReadiumAdapterLCPSQLite', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/3.0.0/Support/CocoaPods/ReadiumAdapterLCPSQLite.podspec'
+ pod 'ReadiumAdapterLCPSQLite', '~> 3.0.0'
```
Then, provide the adapters when initializing the `LCPService`.
@@ -145,73 +205,6 @@ The LCP APIs now accept a `LicenseDocumentSource` enum instead of a URL to an LC
```
-## 3.0.0-alpha.1
-
-### R2 prefix dropped
-
-The `R2` prefix is now deprecated. The `R2Shared`, `R2Streamer` and `R2Navigator` packages were renamed as `ReadiumShared`, `ReadiumStreamer` and `ReadiumNavigator`.
-
-You will need to update your imports, as well as the dependencies you include in your project:
-
-* Swift Package Manager: There's nothing to do.
-* Carthage:
- * Update the Carthage dependencies and make sure the new `ReadiumShared.xcframework`, `ReadiumStreamer.xcframework` and `ReadiumNavigator.xcframework` were built.
- * Replace the old frameworks with the new ones in your project.
-* CocoaPods:
- * Update the `pod` statements in your `Podfile` with the following, before running `pod install`:
- ```
- pod 'ReadiumShared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/3.0.0/Support/CocoaPods/ReadiumShared.podspec'
- pod 'ReadiumStreamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/3.0.0/Support/CocoaPods/ReadiumStreamer.podspec'
- pod 'ReadiumNavigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/3.0.0/Support/CocoaPods/ReadiumNavigator.podspec'
- ```
-
-### Migration of HREFs and Locators (bookmarks, annotations, etc.)
-
- :warning: This requires a database migration in your application, if you were persisting `Locator` objects.
-
- In Readium v2.x, a `Link` or `Locator`'s `href` could be either:
-
- * a valid absolute URL for a streamed publication, e.g. `https://domain.com/isbn/dir/my%20chapter.html`,
- * a percent-decoded path for a local archive such as an EPUB, e.g. `/dir/my chapter.html`.
- * Note that it was relative to the root of the archive (`/`).
-
- To improve the interoperability with other Readium toolkits (in particular the Readium Web Toolkits, which only work in a streaming context) **Readium v3 now generates and expects valid URLs** for `Locator` and `Link`'s `href`.
-
- * `https://domain.com/isbn/dir/my%20chapter.html` is left unchanged, as it was already a valid URL.
- * `/dir/my chapter.html` becomes the relative URL path `dir/my%20chapter.html`
- * We dropped the `/` prefix to avoid issues when resolving to a base URL.
- * Special characters are percent-encoded.
-
- **You must migrate the HREFs or Locators stored in your database** when upgrading to Readium 3. To assist you, two helpers are provided: `AnyURL(legacyHREF:)` and `Locator(legacyJSONString:)`.
-
- Here's an example of a [GRDB migration](https://swiftpackageindex.com/groue/grdb.swift/master/documentation/grdb/migrations) that can serve as inspiration:
-
- ```swift
- migrator.registerMigration("normalizeHREFs") { db in
- let normalizedRows: [(id: Int, href: String, locator: String)] =
- try Row.fetchAll(db, sql: "SELECT id, href, locator FROM bookmarks")
- .compactMap { row in
- guard
- let normalizedHREF = AnyURL(legacyHREF: row["href"])?.string,
- let normalizedLocator = try Locator(legacyJSONString: row["locator"])?.jsonString
- else {
- return nil
- }
- return (row["id"], normalizedHREF, normalizedLocator)
- }
-
- let updateStmt = try db.makeStatement(sql: "UPDATE bookmarks SET href = :href, locator = :locator WHERE id = :id")
- for (id, href, locator) in normalizedRows {
- try updateStmt.execute(arguments: [
- "id": id,
- "href": href
- "locator": locator
- ])
- }
-}
-```
-
-
## 2.7.0
### `AudioNavigator` is now stable