Skip to content
This repository has been archived by the owner on Aug 12, 2022. It is now read-only.

Add the Format API #88

Merged
merged 22 commits into from
May 26, 2020
Merged

Conversation

mickael-menu
Copy link
Member

@mickael-menu mickael-menu commented Apr 16, 2020

Implementation of the Format API proposal.

It's quite a lot of code because I had to integrate ZIP and XML third-party libs in R2Shared and adapt DocumentTypes to be a bit more useful. Here's a few shortcuts to jump directly to the interesting types:

Compared to the existing solution in the Swift toolkit, this new API offers:

  • a centralized place for everything related to formats, it was a bit spread out
  • content sniffing to detect a format when you only have a file (or bytes) without extension nor media type
  • we can now differentiate various JSON-based formats
  • extensibility for custom formats provided by reading apps
  • handling edge cases with media types comparisons, simple equality check is not enough since they can have parameters in different order and they are case-sensitive only for the parameter values

You can see how this new API looks in practice in:

The original Format API proposal is extended a bit to take advantage of iOS capabilities. The sniffing algorithm is going through the provided sniffers, but if no known Format is found, then it falls back on two sources, in order:

  1. The document types declared in the Info.plist, to automatically detect custom formats supported by the reading app without needing custom sniffers.
  2. The system-wide UTIs, to detect any kind of known format. For example, it would work to detect a .xlsx file by returning the following Format generated from system-provided metadata:
Format(
    name: "Office Open XML spreadsheet",
    mediaType: MediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
    fileExtension: "xlsx"
)

A few notes about the implementation:

  • The format detection is fully covered by a unit test suite.
  • To support content sniffing with ZIP and XML, I had to integrate the Minizip and Fuzi third-party libraries. They are not new dependencies per se because they were used in R2Streamer, but now R2Shared has a Cartfile.
  • I added two wrapper APIs: XMLDocument and ZIPArchive to avoid referring directly to third-party dependencies throughout the project, this has several advantages:
    • We'll be able to remove the dependencies in the other projects, since they will be able to use the ones provided by R2Shared.
    • It will be painless to swap dependencies for other third-party libs, since it's only referenced in one file. For ZIP, I already have an implementation for Minizip and ZIPFoundation (which is used in R2LCPClient).
    • We can have a generic test suite for libs implementing these interfaces, which allows to compare them and do benchmarking. Here's an example with ZIP. Having such test suites also provides an automated way to check that a third-party lib is still working as expected after upgrading it.
    • This opens the possibility of using XML/ZIP dependencies provided by reading apps.

@mickael-menu mickael-menu marked this pull request as ready for review April 28, 2020 06:18
Fix sniffing of Readium Audiobook if @type is wrong by falling back on readingOrder sniffing
Add MediaType.isSupportedDocumentType
Add Publication.url(to: String) for hrefs
Add all media types and extensions from the document types' UTIs
Warn against using strict equality with MediaType
@mickael-menu mickael-menu force-pushed the feature/format-api-without-zip+xml branch from 86857ae to 38d95a5 Compare May 1, 2020 08:14
@mickael-menu mickael-menu mentioned this pull request May 16, 2020
@mickael-menu mickael-menu merged commit bc8b9a0 into develop May 26, 2020
@mickael-menu mickael-menu deleted the feature/format-api-without-zip+xml branch May 26, 2020 07:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant