


Il contesto: un saluto, un tap
Tap.me, sviluppata per l’Associazione Anna e Marco E.T.S., ha uno scopo semplice e umano: mandare un saluto alle persone care con un solo tocco. Un tap, e tutti i contatti ricevono una notifica con il tuo messaggio.
L’app era già sul Play Store come PWA (Trusted Web Activity), con backend Node.js e notifiche Web Push. Il problema: metà degli utenti potenziali usa un iPhone, e su iOS quella tecnologia non arriva sull’App Store. Serviva una vera app nativa.
La sfida: quattro vincoli
Niente riscrittura
Una precedente riscrittura in React Native era arrivata a TestFlight dopo 33 build: due codebase da mantenere per sempre. Serviva un’altra strada.
Push native
Le Web Push non funzionano nelle app iOS: andava integrato APNs lato app e lato server, senza rompere i canali esistenti.
Niente Mac
Sviluppo, firma del codice e distribuzione interamente in cloud, senza hardware Apple.
Regole dell’App Store
Cancellazione dell’account in-app, dichiarazione DSA per l’UE, export compliance, certificati e provisioning.
La soluzione: un ponte nativo, non una riscrittura
Abbiamo inserito la web app esistente in un guscio nativo con Capacitor: stessa interfaccia, stesso codice. Un piccolo ponte JavaScript entra in gioco solo su iOS: sostituisce le Web Push con le notifiche native APNs, apre i link esterni fuori dall’app e aggiunge la vibrazione al tocco. Sul web e su Android il codice resta invariato.
┌─ FRONTEND: una sola codebase ─────────────────────┐
│ HTML/CSS/JS · 6 lingue · anche da destra a sx │
│ ponte nativo solo su iOS (Capacitor) │
└──────┬──────────────┬──────────────┬──────────────┘
│ │ │
PWA / TWA App iOS Browser
Play Store App Store Web
│ │ │
┌──────┴──────────────┴──────────────┴──────────────┐
│ BACKEND: Node.js / Express su Railway │
│ MongoDB · JWT · bcrypt · rate limiting │
│ push su 3 canali: Web Push · APNs · FCM │
└───────────────────────────────────────────────────┘
La build iOS avviene interamente in cloud con Codemagic su macOS M2: firma automatica tramite App Store Connect API, numerazione delle build incrementale e caricamento diretto su TestFlight. Dal push su GitHub all’app installabile, nessun Mac coinvolto.
I problemi risolti lungo la strada
Push su più canali. Il server sceglie per ogni dispositivo il canale giusto: Web Push (VAPID) per le PWA, APNs diretto (HTTP/2, con token) per iOS, FCM come canale legacy. I token scaduti vengono ripuliti in automatico.
Una cache che bloccava gli aggiornamenti. Il service worker serviva il codice dalla cache e gli utenti restavano su versioni vecchie anche dopo i rilasci. Risolto con una strategia network-first e un fallback offline.
Recupero password senza email né SMS. Gli account sono legati solo al numero di telefono. La soluzione non costa nulla: il codice di reset arriva come notifica push sui dispositivi registrati, cifrato con bcrypt e valido 15 minuti.
Prefissi internazionali senza migrazioni. Abbiamo aggiunto i numeri esteri mantenendo il riconoscimento dei numeri italiani già registrati, senza toccare il database.
Le regole di Apple. Cancellazione dell’account in-app (linea guida 5.1.1), dichiarazione DSA, export compliance, margini per notch e barra home: i dettagli che separano un’approvazione da un rifiuto.
Registrato in SIAE
Il software Tap.me è depositato presso il Registro Pubblico Speciale per i Programmi per Elaboratore (SIAE), registrazione n. D000029673 del 29/05/2026. Titolare dei diritti: Associazione Anna e Marco E.T.S.
Il risultato: rilasci continui su tre fronti
Gli aggiornamenti web e Android vanno in produzione con un git push e arrivano agli utenti alla riapertura dell’app; iOS segue con una build automatica in cloud su TestFlight. Una sola squadra, una sola codebase, tre piattaforme allineate.
- JavaScript
- Capacitor 8
- Node.js
- Express
- MongoDB
- APNs
- Web Push
- FCM
- Railway
- Codemagic
- GitHub
- PWA / TWA