Skip to content

Commit de7aed2

Browse files
committed
Merge branch 'v3' into documentation
2 parents 72203d9 + 27668a9 commit de7aed2

File tree

363 files changed

+5273
-15971
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

363 files changed

+5273
-15971
lines changed

.github/workflows/checks.yml

+8-8
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ on:
77

88
env:
99
platform: ${{ 'iOS Simulator' }}
10-
device: ${{ 'iPhone 12' }}
10+
device: ${{ 'iPhone 15' }}
1111
commit_sha: ${{ github.sha }}
12+
DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
1213

1314
jobs:
1415
build:
1516
name: Build
16-
runs-on: macos-12
17+
runs-on: macos-13
1718
if: ${{ !github.event.pull_request.draft }}
1819
env:
1920
scheme: ${{ 'Readium-Package' }}
20-
DEVELOPER_DIR: /Applications/Xcode_13.4.1.app/Contents/Developer
2121

2222
steps:
2323
- name: Checkout
@@ -42,7 +42,7 @@ jobs:
4242
4343
lint:
4444
name: Lint
45-
runs-on: macos-12
45+
runs-on: macos-13
4646
if: ${{ !github.event.pull_request.draft }}
4747
env:
4848
scripts: ${{ 'Sources/Navigator/EPUB/Scripts' }}
@@ -76,7 +76,7 @@ jobs:
7676

7777
int-dev:
7878
name: Integration (Local)
79-
runs-on: macos-12
79+
runs-on: macos-13
8080
if: ${{ !github.event.pull_request.draft }}
8181
defaults:
8282
run:
@@ -98,7 +98,7 @@ jobs:
9898
9999
int-spm:
100100
name: Integration (Swift Package Manager)
101-
runs-on: macos-12
101+
runs-on: macos-13
102102
if: ${{ !github.event.pull_request.draft }}
103103
defaults:
104104
run:
@@ -126,7 +126,7 @@ jobs:
126126
127127
int-carthage:
128128
name: Integration (Carthage)
129-
runs-on: macos-12
129+
runs-on: macos-13
130130
if: ${{ !github.event.pull_request.draft }}
131131
defaults:
132132
run:
@@ -157,7 +157,7 @@ jobs:
157157
int-cocoapods:
158158
name: Integration (CocoaPods)
159159
if: github.event_name == 'push'
160-
runs-on: macos-12
160+
runs-on: macos-13
161161
defaults:
162162
run:
163163
working-directory: TestApp

CHANGELOG.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,22 @@ All notable changes to this project will be documented in this file. Take a look
44

55
**Warning:** Features marked as *alpha* may change or be removed in a future release without notice. Use with caution.
66

7-
<!-- ## [Unreleased] -->
7+
## [Unreleased]
8+
9+
### Changed
10+
11+
* The `R2Shared`, `R2Streamer` and `R2Navigator` packages are now called `ReadiumShared`, `ReadiumStreamer` and `ReadiumNavigator`.
12+
* Many APIs now expect one of the new URL types (`RelativeURL`, `AbsoluteURL`, `HTTPURL` and `FileURL`). This is helpful because:
13+
* It validates at compile time that we provide a URL that is supported.
14+
* The API's capabilities are better documented, e.g. a download API could look like this : `download(url: HTTPURL) -> FileURL`.
15+
16+
#### Shared
17+
18+
* `Link` and `Locator`'s `href` are normalized as valid URLs to improve interoperability with the Readium Web toolkits.
19+
* **You MUST migrate your database if you were persisting HREFs and Locators**. Take a look at [the migration guide](Documentation/Migration%20Guide.md) for guidance.
20+
* Links are not resolved to the `self` URL of a manifest anymore. However, you can still normalize the HREFs yourselves by calling `Manifest.normalizeHREFsToSelf()`.
21+
* `Publication.localizedTitle` is now optional, as we cannot guarantee a publication will always have a title.
22+
823

924
## [2.7.0]
1025

Documentation/Guides/Navigator/Preferences.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ This stateless view displays the actual preferences for a fixed-layout publicati
161161
@ViewBuilder func fixedLayoutUserPreferences(
162162
commit: @escaping () -> Void,
163163
scroll: AnyPreference<Bool>? = nil,
164-
fit: AnyEnumPreference<R2Navigator.Fit>? = nil,
164+
fit: AnyEnumPreference<ReadiumNavigator.Fit>? = nil,
165165
pageSpacing: AnyRangePreference<Double>? = nil
166166
) -> some View {
167167
if let scroll = scroll {

Documentation/Migration Guide.md

+75-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,73 @@
22

33
All migration steps necessary in reading apps to upgrade to major versions of the Swift Readium toolkit will be documented in this file.
44

5+
## Unreleased
6+
7+
### R2 prefix dropped
8+
9+
The `R2` prefix is now deprecated. The `R2Shared`, `R2Streamer` and `R2Navigator` packages were renamed as `ReadiumShared`, `ReadiumStreamer` and `ReadiumNavigator`.
10+
11+
You will need to update your imports, as well as the dependencies you include in your project:
12+
13+
* Swift Package Manager: There's nothing to do.
14+
* Carthage:
15+
* Update the Carthage dependencies and make sure the new `ReadiumShared.xcframework`, `ReadiumStreamer.xcframework` and `ReadiumNavigator.xcframework` were built.
16+
* Replace the old frameworks with the new ones in your project.
17+
* CocoaPods:
18+
* Update the `pod` statements in your `Podfile` with the following, before running `pod install`:
19+
```
20+
pod 'ReadiumShared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/3.0.0/Support/CocoaPods/ReadiumShared.podspec'
21+
pod 'ReadiumStreamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/3.0.0/Support/CocoaPods/ReadiumStreamer.podspec'
22+
pod 'ReadiumNavigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/3.0.0/Support/CocoaPods/ReadiumNavigator.podspec'
23+
```
24+
25+
### Migration of HREFs and Locators (bookmarks, annotations, etc.)
26+
27+
:warning: This requires a database migration in your application, if you were persisting `Locator` objects.
28+
29+
In Readium v2.x, a `Link` or `Locator`'s `href` could be either:
30+
31+
* a valid absolute URL for a streamed publication, e.g. `https://domain.com/isbn/dir/my%20chapter.html`,
32+
* a percent-decoded path for a local archive such as an EPUB, e.g. `/dir/my chapter.html`.
33+
* Note that it was relative to the root of the archive (`/`).
34+
35+
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`.
36+
37+
* `https://domain.com/isbn/dir/my%20chapter.html` is left unchanged, as it was already a valid URL.
38+
* `/dir/my chapter.html` becomes the relative URL path `dir/my%20chapter.html`
39+
* We dropped the `/` prefix to avoid issues when resolving to a base URL.
40+
* Special characters are percent-encoded.
41+
42+
**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:)`.
43+
44+
Here's an example of a [GRDB migration](https://swiftpackageindex.com/groue/grdb.swift/master/documentation/grdb/migrations) that can serve as inspiration:
45+
46+
```swift
47+
migrator.registerMigration("normalizeHREFs") { db in
48+
let normalizedRows: [(id: Int, href: String, locator: String)] =
49+
try Row.fetchAll(db, sql: "SELECT id, href, locator FROM bookmarks")
50+
.compactMap { row in
51+
guard
52+
let normalizedHREF = AnyURL(legacyHREF: row["href"])?.string,
53+
let normalizedLocator = try Locator(legacyJSONString: row["locator"])?.jsonString
54+
else {
55+
return nil
56+
}
57+
return (row["id"], normalizedHREF, normalizedLocator)
58+
}
59+
60+
let updateStmt = try db.makeStatement(sql: "UPDATE bookmarks SET href = :href, locator = :locator WHERE id = :id")
61+
for (id, href, locator) in normalizedRows {
62+
try updateStmt.execute(arguments: [
63+
"id": id,
64+
"href": href
65+
"locator": locator
66+
])
67+
}
68+
}
69+
```
70+
71+
572
## 2.7.0
673

774
### `AudioNavigator` is now stable
@@ -56,7 +123,7 @@ Instead, the EPUB, PDF and CBZ navigators expect an instance of `HTTPServer` upo
56123
You can implement your own HTTP server using a third-party library. But the easiest way to migrate is to use the one provided in the new Readium package `ReadiumAdapterGCDWebServer`.
57124
58125
```swift
59-
import R2Navigator
126+
import ReadiumNavigator
60127
import ReadiumAdapterGCDWebServer
61128
62129
let navigator = try EPUBNavigatorViewController(
@@ -167,15 +234,15 @@ Then, rebuild the libraries using `carthage update --platform ios --use-xcframew
167234
If you are using CocoaPods, you will need to update the URL to the Podspecs in your `Podfile`:
168235

169236
```diff
170-
+ pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumShared.podspec'
171-
+ pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumStreamer.podspec'
172-
+ pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumNavigator.podspec'
237+
+ pod 'ReadiumShared', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumShared.podspec'
238+
+ pod 'ReadiumStreamer', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumStreamer.podspec'
239+
+ pod 'ReadiumNavigator', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumNavigator.podspec'
173240
+ pod 'ReadiumOPDS', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumOPDS.podspec'
174241
+ pod 'ReadiumLCP', podspec: 'https://raw.githubusercontent.com/readium/swift-toolkit/2.2.0/Support/CocoaPods/ReadiumLCP.podspec'
175242

176-
- pod 'R2Shared', podspec: 'https://raw.githubusercontent.com/readium/r2-shared-swift/2.2.0/R2Shared.podspec'
177-
- pod 'R2Streamer', podspec: 'https://raw.githubusercontent.com/readium/r2-streamer-swift/2.2.0/R2Streamer.podspec'
178-
- pod 'R2Navigator', podspec: 'https://raw.githubusercontent.com/readium/r2-navigator-swift/2.2.0/R2Navigator.podspec'
243+
- pod 'ReadiumShared', podspec: 'https://raw.githubusercontent.com/readium/r2-shared-swift/2.2.0/ReadiumShared.podspec'
244+
- pod 'ReadiumStreamer', podspec: 'https://raw.githubusercontent.com/readium/r2-streamer-swift/2.2.0/ReadiumStreamer.podspec'
245+
- pod 'ReadiumNavigator', podspec: 'https://raw.githubusercontent.com/readium/r2-navigator-swift/2.2.0/ReadiumNavigator.podspec'
179246
- pod 'ReadiumOPDS', podspec: 'https://raw.githubusercontent.com/readium/r2-opds-swift/2.2.0/ReadiumOPDS.podspec'
180247
- pod 'ReadiumLCP', podspec: 'https://raw.githubusercontent.com/readium/r2-lcp-swift/2.2.0/ReadiumLCP.podspec'
181248
```
@@ -275,7 +342,7 @@ Migrating a project to XCFrameworks is [explained on Carthage's repository](http
275342

276343
#### Troubleshooting
277344

278-
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).
345+
If after migrating to XCFrameworks you experience some build issues like **Could not find module 'ReadiumShared' 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).
279346

280347
### LCP
281348

Makefile

+8-2
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,22 @@ scripts:
1818
@which corepack >/dev/null 2>&1 || (echo "ERROR: corepack is required, please install it first\nhttps://pnpm.io/installation#using-corepack"; exit 1)
1919

2020
cd $(SCRIPTS_PATH); \
21+
rm -rf "node_modules"; \
2122
corepack install; \
2223
pnpm install --frozen-lockfile; \
2324
pnpm run format; \
2425
pnpm run lint; \
2526
pnpm run bundle
2627

28+
.PHONY: update-scripts
29+
update-scripts:
30+
@which corepack >/dev/null 2>&1 || (echo "ERROR: corepack is required, please install it first\nhttps://pnpm.io/installation#using-corepack"; exit 1)
31+
pnpm install --dir "$(SCRIPTS_PATH)"
32+
2733
.PHONY: test
2834
test:
29-
# To limit to a particular test suite: -only-testing:R2SharedTests
30-
xcodebuild test -scheme "Readium-Package" -destination "platform=iOS Simulator,name=iPhone 12" | xcbeautify -q
35+
# To limit to a particular test suite: -only-testing:ReadiumSharedTests
36+
xcodebuild test -scheme "Readium-Package" -destination "platform=iOS Simulator,name=iPhone 15" | xcbeautify -q
3137

3238
.PHONY: lint-format
3339
lint-format:

Package.swift

+17-17
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ let package = Package(
1212
defaultLocalization: "en",
1313
platforms: [.iOS(.v11)],
1414
products: [
15-
.library(name: "R2Shared", targets: ["R2Shared"]),
16-
.library(name: "R2Streamer", targets: ["R2Streamer"]),
17-
.library(name: "R2Navigator", targets: ["R2Navigator"]),
15+
.library(name: "ReadiumShared", targets: ["ReadiumShared"]),
16+
.library(name: "ReadiumStreamer", targets: ["ReadiumStreamer"]),
17+
.library(name: "ReadiumNavigator", targets: ["ReadiumNavigator"]),
1818
.library(name: "ReadiumOPDS", targets: ["ReadiumOPDS"]),
1919
.library(name: "ReadiumLCP", targets: ["ReadiumLCP"]),
2020

@@ -37,7 +37,7 @@ let package = Package(
3737
],
3838
targets: [
3939
.target(
40-
name: "R2Shared",
40+
name: "ReadiumShared",
4141
dependencies: ["ReadiumInternal", "Fuzi", "SwiftSoup", "Zip"],
4242
path: "Sources/Shared",
4343
exclude: [
@@ -53,42 +53,42 @@ let package = Package(
5353
]
5454
),
5555
.testTarget(
56-
name: "R2SharedTests",
57-
dependencies: ["R2Shared"],
56+
name: "ReadiumSharedTests",
57+
dependencies: ["ReadiumShared"],
5858
path: "Tests/SharedTests",
5959
resources: [
6060
.copy("Fixtures"),
6161
]
6262
),
6363

6464
.target(
65-
name: "R2Streamer",
65+
name: "ReadiumStreamer",
6666
dependencies: [
6767
"CryptoSwift",
6868
"Fuzi",
6969
.product(name: "ReadiumGCDWebServer", package: "GCDWebServer"),
7070
"Zip",
71-
"R2Shared",
71+
"ReadiumShared",
7272
],
7373
path: "Sources/Streamer",
7474
resources: [
7575
.copy("Assets"),
7676
]
7777
),
7878
.testTarget(
79-
name: "R2StreamerTests",
80-
dependencies: ["R2Streamer"],
79+
name: "ReadiumStreamerTests",
80+
dependencies: ["ReadiumStreamer"],
8181
path: "Tests/StreamerTests",
8282
resources: [
8383
.copy("Fixtures"),
8484
]
8585
),
8686

8787
.target(
88-
name: "R2Navigator",
88+
name: "ReadiumNavigator",
8989
dependencies: [
9090
"ReadiumInternal",
91-
"R2Shared",
91+
"ReadiumShared",
9292
"DifferenceKit",
9393
"SwiftSoup",
9494
],
@@ -102,16 +102,16 @@ let package = Package(
102102
]
103103
),
104104
.testTarget(
105-
name: "R2NavigatorTests",
106-
dependencies: ["R2Navigator"],
105+
name: "ReadiumNavigatorTests",
106+
dependencies: ["ReadiumNavigator"],
107107
path: "Tests/NavigatorTests"
108108
),
109109

110110
.target(
111111
name: "ReadiumOPDS",
112112
dependencies: [
113113
"Fuzi",
114-
"R2Shared",
114+
"ReadiumShared",
115115
],
116116
path: "Sources/OPDS"
117117
),
@@ -129,7 +129,7 @@ let package = Package(
129129
dependencies: [
130130
"CryptoSwift",
131131
"ZIPFoundation",
132-
"R2Shared",
132+
"ReadiumShared",
133133
.product(name: "SQLite", package: "SQLite.swift"),
134134
],
135135
path: "Sources/LCP",
@@ -152,7 +152,7 @@ let package = Package(
152152
name: "ReadiumAdapterGCDWebServer",
153153
dependencies: [
154154
.product(name: "ReadiumGCDWebServer", package: "GCDWebServer"),
155-
"R2Shared",
155+
"ReadiumShared",
156156
],
157157
path: "Sources/Adapters/GCDWebServer"
158158
),

0 commit comments

Comments
 (0)