L'archiviazione dei dati è uno dei compiti principali di un'applicazione mobile, che influisce su prestazioni, sicurezza ed esperienza utente. In questo articolo tratteremo SQLite, Room, Core Data, Realm, Firebase Firestore, SharedPreferences, DataStore, Keystore e Keychain, oltre ai formati di serializzazione (JSON, Protobuf) e alle librerie (Gson, Moshi, kotlinx.serialization). Questa guida aiuterà gli sviluppatori principianti a scegliere la soluzione di archiviazione dati corretta. Per maggiori informazioni, consulta la guida ufficiale Android sull'archiviazione dati.
Punti chiave
Per archiviare dati strutturati con relazioni tra entità si utilizzano database relazionali.
SQLite è un database relazionale incorporato che funziona su qualsiasi piattaforma mobile. Non richiede un server separato e i dati sono memorizzati in un singolo file. SQLite è la base per Room (Android) e opzionalmente per Core Data (iOS). Librerie: android.database.sqlite (Android), FMDB/Core Data (iOS), sqflite (Flutter).
Room è la libreria ufficiale di Android Architecture Components per lavorare con SQLite. Fornisce un livello ORM: Entity (tabella), DAO (query), Database (punto di ingresso). Room verifica le query SQL in fase di compilazione, supporta coroutine e Flow e migra automaticamente lo schema.
@Entity data class User( @PrimaryKey val id: Int, val name: String, val email: String ) @Dao interface UserDao { @Query("SELECT * FROM user WHERE id = :id") suspend fun getUser(id: Int): User? }
Core Data è il framework di Apple per gestire un grafo di oggetti. Non è un database puro — è un livello di persistenza sopra SQLite, XML o archiviazione binaria. Core Data gestisce oggetti (NSManagedObject), relazioni, versionamento dello schema, annulla/ripeti e multithreading tramite NSManagedObjectContext.
Realm è un'alternativa a SQLite, progettata come database mobile ad alte prestazioni. Realm è più veloce di SQLite in lettura e scrittura, supporta notifiche reattive (Live Objects), crittografia in tempo reale e multipiattaforma (Android, iOS, Flutter, React Native). Svantaggi: dimensione APK/IPA maggiore e consumo di memoria più elevato.
Per archiviare piccole quantità di dati (impostazioni, token, cache) si utilizzano semplici archivi chiave-valore.
SharedPreferences è un archivio chiave-valore legacy in Android. Svantaggi: accesso sincrono (blocca l'interfaccia durante la lettura), mancanza di tipizzazione, rischio ANR durante il caricamento di file grandi. NON consigliato per nuovi progetti.
DataStore è il moderno sostituto di SharedPreferences di Google. Funziona in modo asincrono tramite Kotlin Coroutines e Flow, supporta Preferences DataStore (chiave-valore) e Proto DataStore (dati tipizzati tramite Protobuf). DataStore è sicuro per il thread dell'interfaccia e supporta le transazioni.
UserDefaults è l'archivio standard per piccole impostazioni in iOS. Supporta tipi primitivi, stringhe, date, Data. UserDefaults è sincrono, quindi non adatto per grandi volumi di dati. La registrazione dei valori tramite register(defaults:) imposta i valori predefiniti.
Per l'archiviazione dati in applicazioni che richiedono sincronizzazione tra dispositivi, si utilizzano i database cloud Firebase.
Firebase Firestore è un database documentale NoSQL con sottoscrizioni in tempo reale, scalabilità automatica, query potenti e modalità offline integrata. I dati sono organizzati in raccolte e documenti (strutture simili a JSON). Firestore supporta transazioni e operazioni batch. Ideale per chat, feed e app social.
Firebase Realtime Database è un database NoSQL più vecchio di Firebase che memorizza i dati come un singolo albero JSON. Più semplice di Firestore ma meno flessibile in query e scalabilità. Raccomandato per applicazioni in tempo reale semplici (stato online, chat semplici).
| Caratteristica | Cloud Firestore | Firebase Realtime DB |
|---|---|---|
| Modello dati | Raccolte → Documenti | Albero JSON |
| Query | Complesse (filtraggio, ordinamento, limiti) | Semplici (per chiave) |
| Scalabilità | Automatica | Sharding manuale |
| Modalità offline | Sì (cache persistente) | Sì |
| Prezzo | Per operazioni di lettura/scrittura | Per traffico + archiviazione |
L'archiviazione di token, password e chiavi di crittografia richiede archivi protetti speciali.
Android Keystore è un archivio di sistema per chiavi crittografiche. Le chiavi sono memorizzate in un ambiente hardware (TEE — Trusted Execution Environment), inaccessibile alle app e al sistema operativo. Supporta generazione di chiavi, crittografia e firma. Android 9+ include StrongBox Keymaster (chip dedicato).
Keychain Services è un archivio sicuro iOS per password, chiavi e certificati. I dati sono crittografati utilizzando Secure Enclave hardware. Keychain supporta livelli di accessibilità: Always, WhenUnlocked, WhenUnlockedThisDeviceOnly, AfterFirstUnlock.
EncryptedSharedPreferences è un wrapper su SharedPreferences con crittografia di chiavi e valori tramite AES256-GCM e HKDF. Implementato nella libreria AndroidX Security. Raccomandato per memorizzare token e impostazioni sensibili.
In IT Sectr utilizziamo Android Keystore + EncryptedSharedPreferences per memorizzare token di aggiornamento e chiavi biometriche. Su iOS utilizziamo Keychain con livello kSecAttrAccessibleWhenUnlockedThisDeviceOnly per la massima sicurezza.
Per l'archiviazione di file (immagini, video, documenti), le piattaforme mobili forniscono diversi tipi di archiviazione.
Android distingue tra Internal Storage (/data/data/package/ — archiviazione privata) e External Storage (scheda SD o partizione emulata). Cache Directory è archiviazione temporanea che il sistema può cancellare. Scoped Storage (Android 10+) limita l'accesso a External Storage — le app vedono solo i propri file o file tramite MediaStore/SAF.
iOS fornisce Documents Directory (backup iCloud, dati persistenti), Library/Caches (file temporanei, non sottoposti a backup) e Tmp Directory (temporanei, cancellabili). Utilizza NSFileManager per lavorare con il file system. iOS 11+ supporta File Provider per file cloud.
La serializzazione converte gli oggetti in un formato per la trasmissione o l'archiviazione. La deserializzazione è il processo inverso.
JSON (JavaScript Object Notation) è il formato più popolare: leggibile, flessibile, supportato da tutte le piattaforme. XML è più rigoroso, utilizzato in sistemi legacy. Protobuf (Protocol Buffers) è un formato binario di Google: 3-10 volte più compatto di JSON, analisi più veloce, con schema rigoroso. Utilizzato per sistemi ad alto carico e microservizi.
JSONSerialization è l'API integrata per lavorare con JSON. Codable (Encodable/Decodable) è un protocollo Swift moderno per la serializzazione automatica in JSON, Property List e altri formati.
struct User: Codable { let id: Int let name: String let email: String } let user = User(id: 1, name: "Alice", email: "alice@example.com") let encoder = JSONEncoder() let jsonData = try encoder.encode(user)
Per Flutter e React Native esistono librerie di archiviazione efficienti dedicate.
Hive è un archivio chiave-valore leggero e veloce per Flutter. Non richiede codice nativo (Dart puro), supporta la tipizzazione tramite TypeAdapter e funziona in isolate. Ideale per cache, impostazioni e piccoli volumi di dati.
ObjectBox è un database incorporato ad alte prestazioni per Flutter, Android e iOS. È 10 volte più veloce di SQLite, utilizza una struttura a file piatto per un overhead minimo. Supporta relazioni, query e sottoscrizioni reattive (ObjectBox Dart).
Drift è una libreria SQLite reattiva per Flutter e Dart. Fornisce query type-safe, migrazioni, funzioni DAO e supporto Stream (aggiornamenti reattivi). Drift è la scelta principale per progetti Flutter che richiedono SQLite.
Domande frequenti
La scelta dipende dalla piattaforma: Room (Android) è la libreria ufficiale basata su SQLite con verifica delle query in fase di compilazione. Core Data (iOS) è il framework Apple con grafo di oggetti. Per progetti multipiattaforma, Realm o SQLite tramite ORM sono adatti.
SharedPreferences è una vecchia implementazione con accesso sincrono e rischio ANR. DataStore (Jetpack) è un sostituto moderno basato su Kotlin Coroutines e Flow, che supporta asincronia, tipizzazione e protezione dagli errori.
Android: EncryptedSharedPreferences o Android Keystore. iOS: Keychain Services con accessibilità WhenUnlockedThisDeviceOnly. Per dati critici, utilizzare Secure Enclave (iOS) e Keystore hardware (Android) con biometria.
Cloud Firestore è un database NoSQL di Firebase con sincronizzazione in tempo reale, modalità offline e scalabilità automatica. Adatto per chat, feed di notizie e progetti che necessitano di sincronizzazione tra dispositivi.
Flutter: Hive (chiave-valore veloce), Floor (ORM SQLite), Drift (Moor, SQLite reattivo), ObjectBox (DB incorporato ad alte prestazioni). React Native: Realm, WatermelonDB (caricamento lento) e AsyncStorage (analogo a SharedPreferences).
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.