RECHERCHE-CAPACITOR.md — Native iOS-Hülle via Capacitor + AltStore/SideStore
Stand 06.06.2026. Anlass: Der Barcode-Scan hängt in der iOS-Home-Screen-PWA (WebKit rendert den Kamera-Prompt im standalone-Modus nicht,
getUserMediableibt ewig pending — entschärft durch ADR-31: Permission-Vorabcheck, Timeout, Foto-Fallback). Diese Datei dokumentiert den Plan B: eine native App-Hülle per Capacitor, kostenlos verteilt über AltStore/SideStore (MacBook Pro vorhanden, kein Apple-Developer-Account gewollt, 99 €/Jahr).Vorher testen (Plan A, 0 Minuten Aufwand): Safari → silverscale.dennisfisch.de → aA-Menü → Website-Einstellungen → Kamera → „Erlauben" → PWA neu starten → scannen. Erbt die PWA die Erlaubnis (
permissions.query=granted), lässt der ADR-31-Vorabcheck die Live-Kamera durch und dieser ganze Plan B ist unnötig.
1. Vorab geklärt: Was NICHT geht (Stand 06/2026)
- EU/DMA hilft nicht beim Sideloaden eigener Apps. Alternative Marketplaces (AltStore PAL, Epic) verlangen für die eigene App weiterhin bezahlten Developer-Account + Apple-Notarisierung. Direkte Web-Distribution hat praktisch unerreichbare Hürden. Das kostenlose 7-Tage-Signing ist von der DMA unberührt.
- Blink/Gecko-Browser auf iOS: nicht erschienen. Chromiums iOS-Port ist
weiterhin internes
content_shell(„not a shippable product"), Firefox/Gecko nur GitHub-Diskussionen. Apples Auflagen (separate EU-only-App, Engine nur auf EU-Geräten) machen es für Google/Mozilla unattraktiv; EU-Kommission prüft. Der erste alternative EU-Marketplace hat bereits wieder geschlossen. → „EU-Chrome installiert die PWA mit funktionierender Kamera" bleibt auf absehbare Zeit Zukunftsmusik. Einzelne Blogs, die einen laufenden Rollout behaupten (youngju.dev 05/2026), sind durch keine Primärquelle gedeckt. - WebAuthn/Passkeys funktionieren NICHT in WKWebView → siehe §5, das ist der eine echte Blocker für Silverscale.
2. Architektur der Lösung
┌──────────────────────────────────────┐
│ Native iOS-App (Xcode-Hülle, ~leer) │ ← einmalig bauen, per AltStore signiert
│ ┌────────────────────────────────┐ │
│ │ Capacitor-WKWebView │ │
│ │ lädt LIVE https://silverscale. │ │ ← server.url-Modus: App-Updates kommen
│ │ dennisfisch.de (Remote-Modus) │ │ weiter per npm run build auf dem VPS,
│ └────────────────────────────────┘ │ IPA muss praktisch NIE neu gebaut werden
│ NSCameraUsageDescription │ ← iOS fragt EINMAL nativ, gilt dauerhaft
└──────────────────────────────────────┘
getUserMediafunktioniert in WKWebView seit iOS 14.3 → der bestehende zxing-Live-Scan (ADR-18) liefe unverändert. Der ADR-31-Standalone-Vorabcheck greift dort nicht (display-mode: standalonematcht in der WebView nicht).- Kein neuer Deploy-Weg: die Hülle ist nur ein Browser mit eigener, dauerhafter Kamera-Permission. Optional später: ML-Kit-Barcode-Plugin (schneller als zxing).
3. Teil A — App bauen (einmalig, MacBook Pro)
- Xcode aus dem Mac App Store (gratis, ~12 GB), einmal starten, Command-Line-Tools installieren lassen.
- Frontend-Kopie (muss nicht im Repo passieren):
bash npm i @capacitor/core @capacitor/cli npx cap init Silverscale de.dennisfisch.silverscale npx cap add ios capacitor.config.ts→ Remote-Modus:ts server: { url: 'https://silverscale.dennisfisch.de' }npx cap open ios→ in der Info.plistNSCameraUsageDescription(„Barcode-Scan für Artikel") eintragen.- IPA ohne Signatur bauen (AltStore signiert selbst um; Xcode-Export geht
mit freier Apple-ID nicht regulär):
bash xcodebuild -workspace App.xcworkspace -scheme App -configuration Release \ -sdk iphoneos CODE_SIGNING_ALLOWED=NO build # .app aus DerivedData → Ordner Payload/ → zippen → in Silverscale.ipa umbenennen
4. Teil B — Signieren & Dauerbetrieb (AltStore bzw. SideStore)
AltStore Classic (offiziell, Mac-gebunden)
Einmalig: AltServer auf dem Mac (Menüleisten-App, macOS 11+; ggf.
Mail-Plug-in-Dialog folgen) → iPhone per Kabel → „Install AltStore" →
Apple-ID eingeben (Empfehlung: eigene, leere Apple-ID nur fürs Sideloaden)
→ auf dem iPhone Zertifikat vertrauen (Einstellungen → Allgemein →
VPN & Geräteverwaltung) → Silverscale.ipa per AirDrop → in AltStore „+".
Für den automatischen 7-Tage-Refresh muss GLEICHZEITIG präsent sein:
| Komponente | Zustand |
|---|---|
| MacBook | an und wach (zugeklappt/Ruhezustand = kein Refresh) |
| AltServer | läuft (als Login-Item eintragen) |
| iPhone + Mac | im selben WLAN |
| AltStore-App (iPhone) | Hintergrundaktualisierung an; gelegentlich öffnen hilft |
Verpasster Refresh: App startet ab Tag 7 nicht mehr — kein Datenverlust (alles liegt auf dem VPS), einmal refreshen (WLAN oder Kabel) und gut.
Limits freie Apple-ID: max. 3 aktive Apps inkl. AltStore selbst (→ 2 frei), max. 10 App-IDs pro 7 Tage (nur beim Experimentieren relevant). Jaquelines iPhone = komplett eigenes Setup mit ihrer Apple-ID.
SideStore (Fork, refresht OHNE Mac — empfohlen für unseren Fall)
Nach einmaligem Setup (Pairing-Datei vom Mac + lokaler VPN-Trick „StosVPN" + Anisette-Server) refresht SideStore auf dem iPhone selbst — die „MacBook wach im WLAN"-Pflicht entfällt. Mehr Bastelei beim Einrichten, robusterer Dauerbetrieb, gleiche Apple-ID-Limits. Da das MacBook vermutlich nicht wöchentlich wach im WLAN steht: SideStore bevorzugen.
5. ⚠️ Blocker: Pocket-ID-Passkey-Login
WebAuthn (navigator.credentials) ist in WKWebView gesperrt (nur Apps mit
Browser-Entitlement); der Aufruf hängt sogar, statt sauber zu scheitern.
Der Capacitor-Passkey-Shim (Cap-go) leitet auf native Passkey-APIs um,
braucht aber Associated Domains = bezahltes Developer-Programm.
→ Mit freier Apple-ID kann sich die Capacitor-App nicht per Pocket ID einloggen. Vor Teil A muss serverseitig eine Lösung her, z. B.: - Geräte-Token-Login: eingeloggte PWA/Safari-Session erzeugt in den Einstellungen einen Einmal-Link/QR-Code, der in der App eine normale 180-Tage-Session setzt (kleiner Endpoint + UI-Knopf), oder - Login per ASWebAuthenticationSession-Plugin (System-Browser-Sheet, kann WebAuthn — Session-Cookie landet dann aber nicht automatisch in der WebView, daher Token-Übergabe nötig → läuft auf dasselbe hinaus).
6. Abarbeitungs-Checkliste
- [ ] Plan A testen: Safari-Kamera „Erlauben" → PWA scannen. Klappt's → STOPP, fertig.
- [ ] Falls nein und Foto-Fallback im Alltag nervt:
- [ ] Entscheidung Geräte-Token-Login (Backend-Änderung, §5) — vorher absegnen
- [ ] Xcode + Capacitor-Projekt (§3), IPA bauen
- [ ] SideStore einrichten (§4), App installieren, Kamera-Permission prüfen
- [ ] 7-Tage-Zyklus eine Woche beobachten (überlebt der Auto-Refresh?)
- [ ] Erst bei Begeisterung über 99 €/Jahr (TestFlight, 90 Tage, beide iPhones) nachdenken
Quellen
- AltStore: Install-Anleitung macOS · Troubleshooting/Refresh · AltServer-Releases
- SideStore: Docs · GitHub
- Unsignierte IPAs: Pen Test Partners
- WebAuthn in WKWebView: Apple Dev Forums #705432 · Corbado: Native App Passkeys · Cap-go capacitor-passkey
- DMA/Browser-Engines: Apple: Alternative Browser Engines · Apple: DMA & Apps in der EU · The Register: EU-only-Beschränkung · heise: erster EU-Marketplace schließt · Chromium-Port-Status
- PWA-Kamera-Bug (Anlass): WebKit #185448 · WebKit #215884