Using LCP
Everything below goes through the LCP object. The LcpModule
reference documents each of its methods.
At startup
Initialize LCP once, before any ReadiumView is given an LCP book, and connect your passphrase
UI:
import { LCP } from 'react-native-readium-lcp';
// Resolves false when the app was built without liblcp.
const available = await LCP.initialize();
// Your passphrase UI, or your backend. Resolve undefined to give up.
LCP.setAuthenticationHandler(async ({ reason, hint, provider }) =>
reason === 'passphraseNotFound'
? await api.passphraseHashFor(provider)
: await promptForPassphrase({ hint, wrong: true })
);
initialize takes optional deviceName and deviceId, which identify the device to license
servers when a license is registered. deviceId is generated and stored when you leave it out.
Answering passphrase requests
Readium calls the handler when a license needs its passphrase, while opening a book or reading a
license. The request carries reason (passphraseNotFound, or invalidPassphrase after a wrong
attempt), the license's hint and hintLink, its provider, and the user's details when the
license has them.
Resolve with the passphrase, either in clear text or as its SHA-256 hex hash, or with undefined
to give up. Call LCP.setAuthenticationHandler() with no handler to remove it.
Readium waits on the handler while it opens a book or reads a license. Resolve undefined when the
user cancels, when a newer request replaces the prompt, or when the screen showing the prompt
goes away. A promise that never settles leaves the open or getLicense waiting forever.
On iOS, show the prompt somewhere it can actually appear: a React Native Modal can't be
presented over another Modal, so a prompt opened from a modal screen never shows and the request
hangs.
Acquiring a publication
A license file (.lcpl) points to its publication. acquirePublication downloads the publication
and injects the license into it:
const { localPath, suggestedFilename, licenseId } =
await LCP.acquirePublication(
{ url: lcplUrl }, // or { path: lcplPath } or { json: lcplText }
{ onProgress: (fraction) => setProgress(fraction) }
);
The publication is downloaded to a temporary location: move it somewhere your app keeps books.
A revoked, returned, cancelled or expired license is rejected before anything is downloaded
(licenseRevoked, …). That costs one request to the license server; pass checkStatus: false to
skip it.
To add a license to a publication your app downloaded itself, use
LCP.injectLicense(licenseJSON, publicationPath).
Opening a book
An LCP book opens like any other file:
<ReadiumView file={{ url: bookPath }} />
Readium asks the authentication handler for the passphrase if it doesn't already have it. To skip
the prompt with a passphrase the app already knows, pass it as credentials, preferably as its
SHA-256 hex hash:
<ReadiumView file={{ url: bookPath, credentials: passphraseHash }} />
Like any prop, credentials is visible to React DevTools, so don't log it.
A book that can't be unlocked reports restricted (or cancelled) through
onPublicationError.