Files
lnreader/docs/ios-sidestore.md
masi 89986d5d17 iOS build for sideloading, with the open-lab plugin repository preconfigured
- Background tasks: a JS implementation of the native task module for iOS
  (NativeBackgroundTasksModule.ios.ts) with the Android module's contract:
  per-queue order, 3 concurrent chapter downloads, retries with a delay,
  pause/resume/cancel interruptions, persistence across launches. Tasks run
  while the app is open; periodic library updates and backups are not
  scheduled on iOS. The module is Android-only in autolinking now.
- Reader assets: WKWebView will not load file:// assets into a page whose base
  URL is the source's site, so on iOS the reader CSS, JS and font are inlined
  (scripts/embed-reader-assets.mjs, src/utils/readerAssets). Downloaded
  chapters get a file: base URL and file access on iOS. Android is unchanged.
- Native iOS: downloadFile implemented with URLSession (plugin installs and
  chapter images); volume-button setActive added as a no-op (it is called on
  every chapter).
- Share receiver stub and silent toasts on iOS; TrackSheet uses showToast.
- app.json: bundle id br.dev.marcospaulo.lnreader, http sources allowed, Files
  sharing, deployment target 16.4.
- Fresh installs start with the open-lab plugin repository.
- scripts/build-ios-unsigned.sh and docs/ios-sidestore.md.

Verified on Linux: tsc, eslint, all Jest suites (plus new iOS queue tests),
expo prebuild for iOS, autolinking, and iOS/Android release JS bundles.
Not yet built with Xcode or run on a device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:12:31 -03:00

2.9 KiB

LNReader on iOS (SideStore, free Apple ID)

This fork (open-lab/lnreader, branch ios) builds for iOS. Apple only lets you install your own builds signed with an Apple ID; with a free one the app is valid for 7 days and has to be refreshed. SideStore does the signing and refreshing on the phone itself.

What is different on iOS

Works Not available on iOS
Browsing, plugins (the open-lab repository is preconfigured on a fresh install), reading, Custom code (the illustrator snippet), downloads, EPUB reading, TTS, local library Downloads and library updates in the background: tasks run while the app is open and continue when you return to it. No scheduled library updates or automatic backups.
Downloaded chapters with their images Page turning with the volume buttons (iOS gives apps no volume-key events)
Toast messages, "Share to LNReader", DNS-over-HTTPS, crash-log sharing
Folder and file pickers: EPUB export, backup create and restore

1. Build the .ipa (Mac with Xcode)

git clone https://git.marcospaulo.dev.br/open-lab/lnreader.git
cd lnreader && git switch ios
./scripts/build-ios-unsigned.sh          # -> build/LNReader-unsigned.ipa

Needs Xcode with its command line tools, Node 22.11 or newer, pnpm and CocoaPods (brew install node pnpm cocoapods). The first build takes a while (pods).

Publish it so the phone can download it:

tea releases create --repo open-lab/lnreader --tag ios-$(jq -r .version package.json) \
  --title "iOS $(jq -r .version package.json)" --asset build/LNReader-unsigned.ipa

2. Install SideStore on the iPhone (once)

Follow the current guide at https://docs.sidestore.io (the tools change). As of 2026:

  1. On the iPhone: Settings > Privacy & Security > Developer Mode on (restart when asked).
  2. Install LocalDevVPN from the App Store; SideStore uses it to sign apps on the phone.
  3. On a computer (macOS, Windows or Linux) run iloader, connect the iPhone with a cable, sign in with your Apple ID and install SideStore. It also creates the pairing file SideStore needs.
  4. Open SideStore on the phone and sign in with the same Apple ID.

A free Apple ID allows 3 sideloaded apps at once (SideStore is one) and 10 new app IDs per week.

3. Install LNReader

  1. On the iPhone, open the release page in Safari and download LNReader-unsigned.ipa (it lands in Files > Downloads).
  2. Turn LocalDevVPN on, open SideStore > My Apps > +, and pick the .ipa.
  3. Open LNReader. Under More > Settings > Reader > Custom code > JS, paste the illustrator snippet (it carries your access key, so it is not built in).

Every 7 days

With LocalDevVPN on, open SideStore and tap Refresh All (or let a Shortcuts automation do it daily). If an app expires it stops opening; refreshing brings it back with its data intact. Updating LNReader: build and publish a new .ipa, then install it over the old one from SideStore.