PWA-First Reality in 2026: Installability, iOS Safari, Offline, and the Store Question for Math Challenge
Resumen ejecutivo
PWA-first es viable en 2026, con fronteras técnicas que hay que diseñar, no ignorar. En Chrome/Edge la instalación es automática vía manifest + heurística de compromiso, sin exigir service worker registrado como criterio formal [7]. En iOS Safari sigue siendo manual ("Compartir → Añadir a inicio", sin beforeinstallprompt) [1]; desde iOS 16.4 esto habilita Web Push y Badging API, pero solo si la app está instalada con display: standalone/fullscreen [1][2]. El episodio de la DMA de la UE (2024) fue real — Apple anunció degradar las apps de inicio a marcadores simples en la UE y revirtió antes de iOS 17.4 tras presión pública; hoy la funcionalidad completa persiste en la UE [6]. El almacenamiento mejoró: iOS 17/macOS 14 dan a las apps instaladas ~60% del disco, y quedan exentas de la purga de 7 días que aplica a almacenamiento creado por script sin interacción [4][5]. Background Sync y Periodic Background Sync no existen en Safari ni Firefox (solo Chromium), y Periodic Sync exige app instalada más "engagement score" positivo, sin garantía de frecuencia [15][16] — esto obliga a un mecanismo propio de sincronización al reabrir la app como línea base universal. Para tiendas: PWABuilder/Bubblewrap cubre Android vía Trusted Web Activity [8][9], pero iOS exige Capacitor con capacidades nativas reales para superar la guía 4.2 de Apple contra "recortes web" [12]. Si el producto se orienta a niños, Kids Category (Apple) y Families (Google Play) aplican sin importar la arquitectura [13][14].
Este documento se escribió en inglés; su resumen ejecutivo también existe en español, y esa es la versión de arriba. El cuerpo de abajo es el original en inglés — no está traducido, y no se ofrece una traducción automática en su lugar.
Estado de verificación
Este documento no lleva ninguna marca [unverified]. Cada afirmación está atada a una fuente numerada de abajo.
[unverified] quiere decir que la afirmación está en la investigación pero no se confirmó contra una fuente primaria en la sesión que la produjo. Se publica en vez de borrarse, porque un corpus que esconde sus huecos no es verificable.
Cómo se produjo esta investigación
Los 47 documentos se hicieron el 2026-07-31 por agentes independientes, cada uno con instrucción explícita de no inventar citas y de marcar como [unverified] lo que no pudiera confirmar contra una fuente primaria. La cuota de búsqueda web de la sesión se agotó a media investigación y los agentes posteriores trabajaron por descarga directa contra fuentes primarias. Varios sitios (ftc.gov, ico.org.uk) bloquean la descarga automatizada, y por eso ciertas afirmaciones legales están marcadas a propósito.
Esto es investigación, no asesoría legal, médica ni financiera. Nada aquí reclama un resultado de aprendizaje de Math Challenge; ese estudio todavía no existe.
Capability matrix
| Feature | iOS Safari (installed) | Android Chrome | Desktop Chrome/Edge | Desktop Safari | Verdict |
|---|---|---|---|---|---|
| Install prompt | Manual only, no beforeinstallprompt [1] | Automatic, richer UI (desc.+screenshots) [1][7] | Omnibox icon, beforeinstallprompt [1][7] | Manual “Add to Dock” (Safari 17+), honors shortcuts/categories [1] | Custom install-nudge UI required for iOS only |
| Web Push | 16.4+, install required, gesture-gated, APNs infra, no Dev account needed [2] | Full support, no install gate | Full support | Full support (Safari 16+) | Push cannot be the only pre-install channel on iOS |
| Badging API | Supported for installed apps since 16.4 [2] | Supported | Supported | Unverified this pass | Secondary retention signal only |
| Background Sync | Not supported (all Safari versions) [21] | Supported since Chrome 49 [21] | Supported (Chromium) [21] | Not supported | Chromium-only enhancement, never primary |
| Periodic Background Sync | Not supported | Supported; install + positive engagement score required, frequency not guaranteed [16] | Same caveats | Not supported | Best-effort refresh only |
| Storage quota | ~60% disk once installed (iOS17+); ~1GiB legacy pre-iOS17 [4] | ~60% disk [4] | ~60% (Chromium); Firefox 10%/50% [4] | Same as browser once installed [4] | Ample for problem sets + progress |
| 7-day eviction | Applies to script storage w/ no interaction; installed apps exempt [4][5] | N/A | N/A | N/A | Install removes the biggest iOS data-loss risk |
| OPFS | Baseline widely available since March 2023, incl. Safari [17] | Supported | Supported | Supported | Safe cross-platform local-DB option |
shortcuts/categories | macOS Safari 17.4+; iOS unverified this pass | Supported (long-press) [general knowledge, not re-verified] | Supported | Supported (17.4+) | Low-cost extra, verify on-device |
| Store wrapping | Capacitor (native shell) [11] | PWABuilder/Bubblewrap → TWA → Play [8][9] | PWABuilder → MS Store [10] | N/A | Two different tools, not one |
Findings
1. Installability and manifest fields. Chrome’s published criteria: HTTPS; manifest with short_name/name, icons (192px + 512px), start_url, display in {fullscreen, standalone, minimal-ui, window-controls-overlay}; prefer_related_applications absent/false; not already installed; engagement heuristic (a tap plus ≥30s on page) before beforeinstallprompt fires [7]. Notably, a registered service worker is not a listed criterion in this current guidance — a change from an earlier stricter Chrome rule, worth re-confirming via a live Lighthouse “installable” audit before launch [7]. description/screenshots unlock Chrome’s richer Android install UI [7]. shortcuts/categories are supported on macOS Safari 17.4+ [WebKit 17.4 notes].
2. iOS Safari install reality. No programmatic prompt: install is exclusively Share → “Add to Home Screen” [1]. Since iOS 16.4 this path is also available from Chrome/Edge/Firefox on iOS, all required to run on WebKit, so mechanics and resulting capabilities are identical regardless of which browser icon initiated it [1]. Math Challenge needs an explicit, screenshot-driven “how to install” walkthrough on iOS — it gates push, badging, and the 7-day-eviction exemption [1][2].
3. Web Push and Badging on iOS. Shipped in iOS/iPadOS 16.4 (Feb 2023): requires Home Screen install with display: standalone/fullscreen; permission must follow a direct gesture (e.g., a “Subscribe” button); rides on Apple’s own APNs infrastructure while remaining spec-compliant; needs no Apple Developer Program membership to send [2]. Badging API shipped alongside it for installed apps [2]. Neither works in an ordinary tab/bookmark — install is a hard functional gate, not a preference.
4. Storage and the 7-day eviction rule. Since macOS 14/iOS 17, installed Home Screen apps get the same ~60% disk ceiling as the browser (versus ~15% for embedded WebViews, and a legacy pre-iOS-17 ~1GiB quota) [4]. ITP proactively purges script-writable storage (IndexedDB, Cache API, Web Storage) after 7 days of no interaction, and exempts installed apps [4]. A direct re-fetch of WebKit’s own blog in this session surfaced only the cookie-specific 2019 variant of the 7-day cap (ITP 2.1) [5]; the broader all-script-storage version is corroborated here via MDN as a secondary source, not independently re-confirmed against WebKit’s original post this pass — flagged as a precision gap, though the install-exemption itself is stated plainly [4]. For non-installed iOS users, unsynced local progress risks deletion within a week of inactivity.
5. The 2024 EU DMA episode. Ahead of the DMA deadline, Apple’s Feb 2024 iOS 17.4 beta degraded Home Screen web apps to plain bookmarks in the EU only, citing the burden of supporting non-WebKit engines under DMA. Public/developer backlash (PCMag, iDownloadBlog, Mashable all reported the reversal) led Apple to restore full functionality before the March 1, 2024 general release: “all Home Screen web apps will still be powered by WebKit, regardless of whether the web app is added using Safari or not” [6]. The reversal holds as of this pass, based on 2024 press rather than a fresh 2026 Apple statement — worth a spot-check before launch given how fast this moved once.
6. Android/Chrome: TWA, badging, shortcuts. Android Chrome uses beforeinstallprompt plus richer install UI [7]. WebAPK generation mechanics could not be re-confirmed against a live Chrome doc this session (both likely URLs 404’d) — treated as background context, not a re-verified claim. Confirmed directly: Trusted Web Activity requires Chrome 72+, Digital Asset Links to verify the trust relationship, and falls back to a Custom Tab toolbar otherwise [8].
7. Desktop install. Chrome/Edge: full manifest-driven install via omnibox [7]. Safari macOS (17+): “Add to Dock” from the File menu, no manifest required but honors shortcuts/categories [WebKit 17.4 notes]. Firefox: no manifest-based install [1].
8. Offline strategy. Standard strategies: cache-first, network-first, stale-while-revalidate, network-only, cache-only — “the optimal caching strategy is dependent on the particular web app and how it is used” [18]. Workbox precaches a defined asset list at install time; MDN’s worked example shows cache-first with network fallback and a final offline page [18][19]. For a learning app: precache app shell + offline-fallback page; cache-first for versioned static content (fonts, icons, bundled problem sets); stale-while-revalidate/network-first for leaderboards, streaks, session data [18][19].
9. Syncing offline attempts, anti-cheat, leaderboards. Background Sync fires a one-off retry once connectivity returns, but under hard limits — ~30s idle timeout, 30s sync JS execution cap, 5-minute waitUntil() ceiling, after which the worker is killed and restarts on the next attempt [19]. It’s Chromium-only (unsupported on every Safari version) [21], and Periodic Background Sync additionally needs install plus a positive engagement score with unguaranteed frequency [16] — neither exists on iOS at all. The only universally reliable mechanism is a foreground-triggered flush: queue attempts in IndexedDB, flush on visibilitychange/focus/resume, with Background Sync layered on top only as a best-effort Android accelerator. MDN does not prescribe conflict resolution beyond the retry/timeout primitives [19] — the following is Math Challenge’s own design reasoning, not a sourced claim: never trust a client-computed score arriving offline; sync the raw answer/timing log and have the server recompute correctness and leaderboard eligibility server-side, closing the obvious offline-cheat vector.
10. Local storage options. IndexedDB/Cache API share the quota pool from §4. OPFS is Baseline widely available since March 2023 across evergreen browsers including Safari, offers synchronous byte-level access in Web Workers (useful for a bundled SQLite-style problem bank), shares the same quota, and clears with site storage [17]. localStorage/sessionStorage stay capped near 5MiB and are synchronous — small flags only, not app data [4].
11. Performance budget on low-end Android. RAIL: respond to input within 100ms (~50ms budget after idle work), render frames within 10ms (of a 16ms budget), do idle work in ≤50ms chunks, reach interactive within 5s on a mid-range device over slow 3G (reference: Moto G4, 400ms RTT/400kbps), subsequent loads under 2s [20]. This directly bounds precache payload and initial bundle size.
12. Store wrapping and guideline 4.2. PWABuilder is “powered by Bubblewrap and uses the same underlying core” [9]; Bubblewrap (GoogleChromeLabs CLI) scaffolds a TWA-based Android project for Play Store [9]; PWABuilder can also target the Microsoft Store [10]. iOS needs Capacitor — a real native shell (Swift) with genuine native API access, not a bare WebView [11]. Apple’s guideline 4.2 requires apps to go “beyond a repackaged website,” and 4.2.2 explicitly bars apps that are primarily “web clippings, content aggregators, or a collection of links” [12]. 4.2.6 bars app-factory templates unless submitted by the content provider directly — which favors Math Challenge as first-party owner [12]. Clearing 4.2 means shipping real native capability inside the shell (native push, native share, offline-first data), not just pointing a WebView at a URL.
13. Kids Category / Families — architecture-independent. Apple’s Kids Category (guidelines 1.3, 5.1.4) requires an age band, bars sending PII/device info to third parties without parental consent, requires human-reviewed age-appropriate ads if shown, requires parental gates before external links/IAP/store prompts, and Ask to Buy [13]. Google Play Families similarly requires age-appropriate content, bars webview-only apps driving external traffic, restricts ads to Families Self-Certified SDKs, bars interest-based ads and AAID/precise-location collection for kids-only apps, and requires safety UX for social features [14]. Neither policy carves out an exception for hybrid/PWA-wrapped apps — both regulate behavior and data practices, not the tech stack [13][14].
Design implications
- Manifest baseline:
name,short_name,icons(192px + 512px + maskable variant),start_url,display: "standalone",theme_color,background_color,description,screenshots— the last two unlock Chrome’s richer Android install UI at no cost [7]. - Don’t rely on
beforeinstallpromptcross-platform. Build a custom, screenshot-driven “Add to Home Screen” walkthrough for iOS as mandatory onboarding — it gates push, badging, and the 7-day eviction exemption there [1][2][4]. - Ship a service worker regardless of the Chrome criterion change. Precache app shell + offline-fallback page; cache-first for versioned static assets; stale-while-revalidate/network-first for leaderboard/session data [7][18][19].
- Design push for the iOS floor, not the Android ceiling. Push only works post-install with
display: standalone/fullscreen; gate the permission ask behind an explicit value message and a deliberate gesture [2]. - Treat “not installed” as a distinct, lower-trust state on iOS. Non-installed local progress risks 7-day eviction; treat writes for that cohort as ephemeral and actively nudge toward install rather than silently accumulating data that may vanish [4].
- Offline queue must be foreground-triggered everywhere. Queue attempts in IndexedDB with a client idempotency key + device timestamp; flush on
visibilitychange/focus/resume on every platform; layer Background Sync on top only for Android as a best-effort accelerator, never the relied-upon path [15][16][19]. - Anti-cheat via server-side recompute. Never trust a client-computed score from an offline queue. Sync the raw answer/timing event log; the server recomputes correctness and leaderboard score from that log — closing the offline-fabrication vector (Math Challenge’s own reasoning, not sourced).
- Leaderboard consistency: an offline-completed attempt posts as “pending” until server revalidation, using the idempotency key from #6 to dedupe flaky-connection resubmits.
- Local data store: IndexedDB for structured data (progress, queue, cached content), not
localStorage/sessionStorage(sync, ~5MiB cap); consider OPFS only if a heavier embedded DB (e.g., wa-sqlite problem bank) is needed, since it’s Baseline widely available including Safari [4][17]. - Performance budget: interactive within 5s on a mid-range Android device over slow 3G, under 2s on repeat loads, animation work within a 10ms/frame budget — bounds both bundle size and precache payload [20].
- Badging as secondary signal only (“N pending challenges”), never a load-bearing notification channel, since desktop Safari support wasn’t independently re-verified this pass [2].
- Store wrapping is a later, optional phase, two different tools. Android: PWABuilder/Bubblewrap → TWA → Play Store with Digital Asset Links [8][9]. iOS: Capacitor with real native capability (native push, native share, offline-first data) specifically to survive guideline 4.2/4.2.2 — a bare WebView will not pass review [11][12].
- Design for Kids Category/Families now if that positioning is contemplated: no third-party analytics/ad SDK sending child PII without consent, certified kid-safe ad networks only if any ads, a parental gate before external links/IAP/store prompts, and an explicit age-band decision — none of this is avoided by staying PWA-first [13][14].
- Re-verify DMA status and the service-worker-criterion claim close to launch. Both are policy/implementation details that already moved once (DMA reversed within a month in 2024; Chrome dropped a formerly-required service worker check) — a pre-launch Lighthouse audit and a check of Apple’s current EU terms are cheap insurance [6][7].
Open questions for the project owner
- For iOS users who never install, is an ephemeral (7-day-eviction) local experience acceptable, or should saved progress/leaderboards hard-gate behind installation?
- Should offline-synced attempts hide from the leaderboard entirely until server revalidation, or show a provisional “pending verification” score?
- Is a Kids Category (Apple) / Families (Google Play) positioning actually planned, or is the audience “students + parents” broadly — this changes the analytics/ads vendor shortlist materially?
- Given the two-different-tools reality for store wrapping (TWA for Android vs. Capacitor for iOS), is store presence a near-term roadmap item worth architecting for now, or fully deferred?
- Should the team budget an on-device verification pass (real iPhone + low-end Android) to confirm the items flagged unverified here — desktop Safari badging, iOS
shortcuts/categories, current DMA/EU status — before committing to these implications?
Fuentes
- MDN, "Making PWAs installable"
- WebKit Blog, "Web Push for Web Apps on iOS and iPadOS"
- Math Challenge internal research, topic 19 (habit loops/push) — docs/research/2026-07-31-mc-19-habit-loops-push-notifications.md
- MDN, "Storage quotas and eviction criteria"
- WebKit Blog, "Intelligent Tracking Prevention 2.1"
- Press coverage of Apple's March 2024 EU DMA reversal (PCMag, iDownloadBlog, Mashable), dated ~2024-03-01, retrieved via search snippet 2026-07-31 — not independently re-confirmed against a live Apple statement
- web.dev, "Installability criteria"
- Chrome Developers, "Trusted Web Activity"
- GitHub, GoogleChromeLabs/bubblewrap
- PWABuilder
- Capacitor documentation
- Apple, "App Store Review Guidelines" §4.2
- Apple Developer, "Kids Category"
- Google Play, Families policy requirements
- Caniuse, "Background Sync"
- Chrome Developers, "Periodic Background Sync"
- MDN, "Origin Private File System"
- web.dev, PWA course, "Workbox" chapter
- MDN, "Offline and background operation"
- web.dev, "The RAIL performance model"
- MDN, "Badging API" cross-checked against caniuse Background Sync table
Preguntas que este documento le deja abiertas al dueño
Están sin responder a propósito. Se listan, no se resuelven — convertirlas en preguntas frecuentes obligaría a inventar respuestas que el documento no tiene.
- For iOS users who never install, is an ephemeral (7-day-eviction) local experience acceptable, or should saved progress/leaderboards hard-gate behind installation?
- Should offline-synced attempts hide from the leaderboard entirely until server revalidation, or show a provisional "pending verification" score?
- Is a Kids Category (Apple) / Families (Google Play) positioning actually planned, or is the audience "students + parents" broadly — this changes the analytics/ads vendor shortlist materially?
- Given the two-different-tools reality for store wrapping (TWA for Android vs. Capacitor for iOS), is store presence a near-term roadmap item worth architecting for now, or fully deferred?
- Should the team budget an on-device verification pass (real iPhone + low-end Android) to confirm the items flagged unverified here — desktop Safari badging, iOS shortcuts/categories, current DMA/EU status — before committing to these implications?
Uno de 51 documentos de investigación, 168.346 palabras en total, contadas en el build sobre los archivos mismos. Leer este documento en el repositorio