Przechowywanie danych to jedno z kluczowych zadań aplikacji mobilnej, wpływające na wydajność, bezpieczeństwo i doświadczenie użytkownika. W tym artykule omówimy SQLite, Room, Core Data, Realm, Firebase Firestore, SharedPreferences, DataStore, Keystore i Keychain, a także formaty serializacji (JSON, Protobuf) i biblioteki (Gson, Moshi, kotlinx.serialization). Ten przewodnik pomoże początkującym programistom wybrać odpowiednie rozwiązanie do przechowywania danych. Więcej informacji w oficjalnym przewodniku Android dotyczącym przechowywania danych.
Najważniejsze punkty
Do przechowywania danych strukturalnych z relacjami między encjami używa się relacyjnych baz danych.
SQLite to osadzona relacyjna baza danych działająca na każdej platformie mobilnej. Nie wymaga osobnego serwera, dane są przechowywane w jednym pliku. SQLite jest podstawą dla Room (Android) i opcjonalnie dla Core Data (iOS). Biblioteki: android.database.sqlite (Android), FMDB/Core Data (iOS), sqflite (Flutter).
Room to oficjalna biblioteka Android Architecture Components do pracy z SQLite. Zapewnia warstwę ORM: Entity (tabela), DAO (zapytania), Database (punkt wejścia). Room sprawdza zapytania SQL w czasie kompilacji, obsługuje korutyny i Flow oraz automatycznie migruje schemat.
@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 to framework Apple do zarządzania grafem obiektów. Nie jest czystą bazą danych — to warstwa trwałości na SQLite, XML lub magazynie binarnym. Core Data zarządza obiektami (NSManagedObject), relacjami, versionowaniem schematu, cofaniem/powtarzaniem i wielowątkowością przez NSManagedObjectContext.
Realm to alternatywa dla SQLite, zaprojektowana jako wysokowydajna mobilna baza danych. Realm jest szybszy od SQLite przy odczycie i zapisie, obsługuje powiadomienia reaktywne (Live Objects), szyfrowanie w locie i wieloplatformowość (Android, iOS, Flutter, React Native). Wady: zwiększony rozmiar APK/IPA i większe zużycie pamięci.
Do przechowywania małych ilości danych (ustawienia, tokeny, pamięć podręczna) używa się prostych magazynów klucz-wartość.
SharedPreferences to przestarzały magazyn klucz-wartość w Androidzie. Wady: dostęp synchroniczny (blokuje UI podczas odczytu), brak typowania, ryzyko ANR podczas ładowania dużego pliku. NIE zalecane dla nowych projektów.
DataStore to nowoczesny zamiennik SharedPreferences od Google. Działa asynchronicznie przez Kotlin Coroutines i Flow, obsługuje Preferences DataStore (klucz-wartość) i Proto DataStore (dane typowane przez Protobuf). DataStore jest bezpieczny dla wątku UI i obsługuje transakcje.
UserDefaults to standardowy magazyn dla małych ustawień w iOS. Obsługuje typy prymitywne, ciągi znaków, daty, Data. UserDefaults jest synchroniczny, więc nie nadaje się do dużych wolumenów danych. Rejestracja wartości przez register(defaults:) ustawia wartości domyślne.
Do przechowywania danych w aplikacjach wymagających synchronizacji między urządzeniami używa się baz danych Firebase w chmurze.
Firebase Firestore to dokumentowa baza danych NoSQL z subskrypcjami w czasie rzeczywistym, automatycznym skalowaniem, potężnymi zapytaniami i wbudowanym trybem offline. Dane są organizowane w kolekcje i dokumenty (struktury podobne do JSON). Firestore obsługuje transakcje i operacje wsadowe. Idealny do czatów, kanałów i aplikacji społecznościowych.
Firebase Realtime Database to starsza baza NoSQL Firebase przechowująca dane jako pojedyncze drzewo JSON. Prostsza niż Firestore, ale mniej elastyczna w zapytaniach i skalowaniu. Zalecana do prostych aplikacji czasu rzeczywistego (status online, proste czaty).
| Cecha | Cloud Firestore | Firebase Realtime DB |
|---|---|---|
| Model danych | Kolekcje → Dokumenty | Drzewo JSON |
| Zapytania | Złożone (filtrowanie, sortowanie, limity) | Proste (po kluczu) |
| Skalowanie | Automatyczne | Ręczne shardowanie |
| Tryb offline | Tak (trwała pamięć podręczna) | Tak |
| Cena | Za operacje odczytu/zapisu | Za ruch + przechowywanie |
Przechowywanie tokenów, haseł i kluczy szyfrowania wymaga specjalnych chronionych magazynów.
Android Keystore to systemowy magazyn kluczy kryptograficznych. Klucze są przechowywane w środowisku sprzętowym (TEE — Trusted Execution Environment), niedostępnym dla aplikacji i systemu operacyjnego. Obsługuje generowanie kluczy, szyfrowanie i podpisywanie. Android 9+ zawiera StrongBox Keymaster (dedykowany układ).
Keychain Services to bezpieczny magazyn iOS dla haseł, kluczy i certyfikatów. Dane są szyfrowane przy użyciu sprzętowego Secure Enclave. Keychain obsługuje poziomy dostępności: Always, WhenUnlocked, WhenUnlockedThisDeviceOnly, AfterFirstUnlock.
EncryptedSharedPreferences to otoka wokół SharedPreferences z szyfrowaniem kluczy i wartości przez AES256-GCM i HKDF. Zaimplementowana w bibliotece AndroidX Security. Zalecana do przechowywania tokenów i poufnych ustawień.
W IT Sectr używamy Android Keystore + EncryptedSharedPreferences do przechowywania tokenów odświeżania i kluczy biometrycznych. Na iOS używamy Keychain z poziomem kSecAttrAccessibleWhenUnlockedThisDeviceOnly dla maksymalnego bezpieczeństwa.
Do przechowywania plików (obrazy, wideo, dokumenty) platformy mobilne zapewniają kilka typów magazynów.
Android rozróżnia Internal Storage (/data/data/pakiet/ — prywatny magazyn) i External Storage (karta SD lub partycja emulowana). Cache Directory to tymczasowy magazyn, który system może wyczyścić. Scoped Storage (Android 10+) ogranicza dostęp do External Storage — aplikacje widzą tylko własne pliki lub pliki przez MediaStore/SAF.
iOS zapewnia Documents Directory (kopia zapasowa iCloud, dane trwałe), Library/Caches (pliki tymczasowe, bez kopii zapasowej) i Tmp Directory (tymczasowe, mogą być wyczyszczone). Użyj NSFileManager do pracy z systemem plików. iOS 11+ obsługuje File Provider dla plików w chmurze.
Serializacja konwertuje obiekty do formatu transmisji lub przechowywania. Deserializacja to proces odwrotny.
JSON (JavaScript Object Notation) to najpopularniejszy format: czytelny, elastyczny, obsługiwany przez wszystkie platformy. XML jest bardziej rygorystyczny, używany w systemach legacy. Protobuf (Protocol Buffers) to binarny format Google: 3-10 razy bardziej kompaktowy niż JSON, szybsze parsowanie, ścisły schemat. Używany w systemach wysokiego obciążenia i mikrousługach.
JSONSerialization to wbudowane API do pracy z JSON. Codable (Encodable/Decodable) to nowoczesny protokół Swift do automatycznej serializacji do JSON, Property List i innych formatów.
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)
Dla Flutter i React Native istnieją własne wydajne biblioteki przechowywania.
Hive to lekki, szybki magazyn klucz-wartość dla Flutter. Nie wymaga natywnego kodu (czysty Dart), obsługuje typowanie przez TypeAdapter, działa w izolatach. Idealny do pamięci podręcznej, ustawień i małych wolumenów danych.
ObjectBox to wysokowydajna osadzona baza danych dla Flutter, Android i iOS. Jest 10+ razy szybsza niż SQLite, używa płaskiej struktury plików dla minimalnego narzutu. Obsługuje relacje, zapytania i reaktywne subskrypcje (ObjectBox Dart).
Drift to reaktywna biblioteka SQLite dla Flutter i Dart. Zapewnia bezpieczne typowo zapytania, migracje, funkcje DAO i wsparcie Stream (reaktywne aktualizacje). Drift to podstawowy wybór dla projektów Flutter wymagających SQLite.
Często zadawane pytania
Wybór zależy od platformy: Room (Android) to oficjalna biblioteka oparta na SQLite ze sprawdzaniem zapytań w czasie kompilacji. Core Data (iOS) to framework Apple z grafem obiektów. Do projektów wieloplatformowych odpowiedni jest Realm lub SQLite przez ORM.
SharedPreferences to stara implementacja z synchronicznym dostępem i ryzykiem ANR. DataStore (Jetpack) to nowoczesny zamiennik oparty na Kotlin Coroutines i Flow, obsługujący asynchroniczność, typowanie i ochronę przed błędami.
Android: EncryptedSharedPreferences lub Android Keystore. iOS: Keychain Services z dostępnością WhenUnlockedThisDeviceOnly. Do krytycznych danych używaj Secure Enclave (iOS) i sprzętowego Keystore (Android) z biometrią.
Cloud Firestore to baza danych NoSQL od Firebase z synchronizacją w czasie rzeczywistym, trybem offline i automatycznym skalowaniem. Odpowiednia do czatów, kanałów informacyjnych i projektów wymagających synchronizacji między urządzeniami.
Flutter: Hive (szybki klucz-wartość), Floor (ORM SQLite), Drift (Moor, reaktywny SQLite), ObjectBox (wydajna osadzona BD). React Native: Realm, WatermelonDB (leniwe ładowanie) i AsyncStorage (analog SharedPreferences).
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.