Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,19 @@ All notable changes to this project will be documented in this file. Take a look

## [Unreleased]

### Added

#### LCP

* Support for streaming an LCP-protected publication from its License Document (LCPL). [Take a look at the LCP guide for more information](docs/Guides/Readium%20LCP.md#streaming-an-lcp-protected-package).

### Changed

#### Shared

* The `absoluteURL` and `relativeURL` extensions on `URLConvertible` were removed as they conflict with the native `URL.absoluteURL`.
* If you were using them, you can for example still use `anyURL.absoluteURL` instead.

#### Streamer

* A `self` link is not required anymore when parsing a RWPM.
Expand All @@ -21,10 +32,6 @@ All notable changes to this project will be documented in this file. Take a look

* Support for streaming ZIP packages over HTTP. This lets you open a remote EPUB, audiobook, or any other ZIP-based publication without needing to download it first.

#### LCP

* Support for streaming an LCP-protected publication from its License Document (LCPL). [Take a look at the LCP guide for more information](docs/Guides/Readium%20LCP.md#streaming-an-lcp-protected-package).

### Deprecated

* The `close()` and `Closeable` APIs are now deprecated. Resources are automatically released upon `deinit`, which aligns better with Swift.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Navigator/Audiobook/PublicationMediaLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ private let schemePrefix = "readium"

extension URL {
var audioHREF: AnyURL? {
guard let url = absoluteURL, url.scheme.rawValue.hasPrefix(schemePrefix) == true else {
guard let url = anyURL.absoluteURL, url.scheme.rawValue.hasPrefix(schemePrefix) == true else {
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/Shared/Toolkit/File/FileContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public final class FileContainer: Container, Loggable {

public subscript(url: any URLConvertible) -> Resource? {
guard
let url = url.relativeURL?.normalized,
let url = url.anyURL.relativeURL?.normalized,
let file = files[url]
else {
return nil
Expand Down
8 changes: 3 additions & 5 deletions Sources/Shared/Toolkit/URL/Absolute URL/AbsoluteURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public extension AbsoluteURL {
/// returns bar/baz
func relativize<T: URLConvertible>(_ other: T) -> RelativeURL? {
guard
let absoluteURL = other.absoluteURL,
let absoluteURL = other.anyURL.absoluteURL,
scheme == absoluteURL.scheme,
origin == absoluteURL.origin
else {
Expand All @@ -75,16 +75,14 @@ public extension AbsoluteURL {

/// Indicates whether the receiver is relative to the given `base` URL.
func isRelative<T: URLConvertible>(to base: T) -> Bool {
base.absoluteURL?.scheme == scheme
&& base.absoluteURL?.origin == origin
base.anyURL.absoluteURL?.scheme == scheme
&& base.anyURL.absoluteURL?.origin == origin
}
}

/// Implements ``URLConvertible``.
public extension AbsoluteURL {
var anyURL: AnyURL { .absolute(self) }
var relativeURL: RelativeURL? { nil }
var absoluteURL: AbsoluteURL? { self }
}

/// A URL scheme, e.g. http or file.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Shared/Toolkit/URL/Absolute URL/FileURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ public struct FileURL: AbsoluteURL, Hashable, Sendable {
public extension URLConvertible {
/// Returns a `FileURL` if the URL has a `file` scheme.
var fileURL: FileURL? {
(absoluteURL as? FileURL) ?? FileURL(url: anyURL.url)
(anyURL.absoluteURL as? FileURL) ?? FileURL(url: anyURL.url)
}
}
2 changes: 1 addition & 1 deletion Sources/Shared/Toolkit/URL/Absolute URL/HTTPURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ public struct HTTPURL: AbsoluteURL, Hashable, Sendable {
public extension URLConvertible {
/// Returns an `HTTPURL` if the URL has an `http` or `https` scheme.
var httpURL: HTTPURL? {
(absoluteURL as? HTTPURL) ?? HTTPURL(url: anyURL.url)
(anyURL.absoluteURL as? HTTPURL) ?? HTTPURL(url: anyURL.url)
}
}
30 changes: 16 additions & 14 deletions Sources/Shared/Toolkit/URL/AnyURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ public enum AnyURL: URLProtocol {
}
}

/// Returns the wrapped ``RelativeURL``, if this URL is relative.
public var relativeURL: RelativeURL? {
guard case let .relative(url) = self else {
return nil
}
return url
}

/// Returns the wrapped ``AbsoluteURL``, if this URL is absolute.
public var absoluteURL: AbsoluteURL? {
guard case let .absolute(url) = self else {
return nil
}
return url
}

private var wrapped: URLProtocol {
switch self {
case let .absolute(url):
Expand Down Expand Up @@ -104,20 +120,6 @@ public enum AnyURL: URLProtocol {
/// Implements `URLConvertible`.
extension AnyURL: URLConvertible {
public var anyURL: AnyURL { self }

public var relativeURL: RelativeURL? {
guard case let .relative(url) = self else {
return nil
}
return url
}

public var absoluteURL: AbsoluteURL? {
guard case let .absolute(url) = self else {
return nil
}
return url
}
}

/// Implements `Hashable` and `Equatable`.
Expand Down
6 changes: 2 additions & 4 deletions Sources/Shared/Toolkit/URL/RelativeURL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public struct RelativeURL: URLProtocol, Hashable {
/// returns foo/baz
public func resolve<T: URLConvertible>(_ other: T) -> AnyURL? {
// other is absolute?
guard let relativeURL = other.relativeURL else {
guard let relativeURL = other.anyURL.relativeURL else {
return other.anyURL
}
return resolve(relativeURL)?.anyURL
Expand Down Expand Up @@ -84,7 +84,7 @@ public struct RelativeURL: URLProtocol, Hashable {
/// returns baz
public func relativize<T: URLConvertible>(_ other: T) -> RelativeURL? {
guard
let relativeURL = other.relativeURL,
let relativeURL = other.anyURL.relativeURL,
relativeURL.string.hasPrefix(string)
else {
return nil
Expand Down Expand Up @@ -112,8 +112,6 @@ public struct RelativeURL: URLProtocol, Hashable {
/// Implements `URLConvertible`.
extension RelativeURL: URLConvertible {
public var anyURL: AnyURL { .relative(self) }
public var relativeURL: RelativeURL? { self }
public var absoluteURL: AbsoluteURL? { nil }
}

public extension RelativeURL {
Expand Down
13 changes: 0 additions & 13 deletions Sources/Shared/Toolkit/URL/URLConvertible.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,6 @@ import Foundation
public protocol URLConvertible {
/// Converts the receiver to an ``AnyURL``.
var anyURL: AnyURL { get }

/// Converts the receiver to a ``RelativeURL``, if the represented URL is
/// relative.
var relativeURL: RelativeURL? { get }

/// Converts the receiver to an ``AnyAbsoluteURL``, if the represented URL
/// is absolute.
var absoluteURL: AbsoluteURL? { get }
}

public extension URLConvertible {
var relativeURL: RelativeURL? { anyURL.relativeURL }
var absoluteURL: AbsoluteURL? { anyURL.absoluteURL }
}

extension URL: URLConvertible {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Shared/Toolkit/ZIP/Minizip/MinizipContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ final class MinizipContainer: Container, Loggable {

subscript(url: any URLConvertible) -> (any Resource)? {
guard
let url = url.relativeURL?.normalized,
let url = url.anyURL.relativeURL?.normalized,
let metadata = entriesMetadata[url]
else {
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ final class ZIPFoundationContainer: Container, Loggable {

subscript(url: any URLConvertible) -> (any Resource)? {
guard
let url = url.relativeURL?.normalized,
let url = url.anyURL.relativeURL?.normalized,
let entry = entriesByPath[url]
else {
return nil
Expand Down
20 changes: 10 additions & 10 deletions TestApp/Integrations/Local/TestApp.xctestplan
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,36 @@
{
"target" : {
"containerPath" : "container:..",
"identifier" : "R2NavigatorTests",
"name" : "R2NavigatorTests"
"identifier" : "ReadiumInternalTests",
"name" : "ReadiumInternalTests"
}
},
{
"target" : {
"containerPath" : "container:..",
"identifier" : "R2SharedTests",
"name" : "R2SharedTests"
"identifier" : "ReadiumOPDSTests",
"name" : "ReadiumOPDSTests"
}
},
{
"target" : {
"containerPath" : "container:..",
"identifier" : "R2StreamerTests",
"name" : "R2StreamerTests"
"identifier" : "ReadiumNavigatorTests",
"name" : "ReadiumNavigatorTests"
}
},
{
"target" : {
"containerPath" : "container:..",
"identifier" : "ReadiumInternalTests",
"name" : "ReadiumInternalTests"
"identifier" : "ReadiumSharedTests",
"name" : "ReadiumSharedTests"
}
},
{
"target" : {
"containerPath" : "container:..",
"identifier" : "ReadiumOPDSTests",
"name" : "ReadiumOPDSTests"
"identifier" : "ReadiumStreamerTests",
"name" : "ReadiumStreamerTests"
}
}
],
Expand Down
2 changes: 1 addition & 1 deletion TestApp/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
guard let url = url.absoluteURL, let vc = window?.rootViewController else {
guard let url = url.anyURL.absoluteURL, let vc = window?.rootViewController else {
return false
}

Expand Down
2 changes: 1 addition & 1 deletion TestApp/Sources/Library/LibraryService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ final class LibraryService: Loggable {
/// Imports a bunch of publications.
func importPublications(from sourceURLs: [URL], sender: UIViewController) async throws {
for url in sourceURLs {
guard let url = url.absoluteURL else {
guard let url = url.anyURL.absoluteURL else {
continue
}
try await importPublication(from: url, sender: sender, progress: { _ in })
Expand Down