V mobilním vývoji jsou práce s daty, cachování a synchronizace tři klíčové aspekty určující výkon a spolehlivost aplikace. Podle Google Android Architecture Guide správná architektura zpracování dat přímo ovlivňuje rychlost odezvy a uživatelský zážitek. Vzor Repository poskytuje jediný přístupový bod ke všem zdrojům dat.
Klíčové Body
Vzor Repository je architektonický přístup, kde jedna třída repozitáře spravuje všechny operace s daty a abstrahuje vzdálená REST API a lokální úložiště Room nebo SwiftData. Tento způsob práce s daty umožňuje aplikaci získat informace nejprve z Memory Cache nebo Disk Cache a poté ze sítě, čímž se zkracuje doba odezvy. V mobilním vývoji se Repository stal de facto standardem díky doporučením Google a Apple.
Remote Data Source poskytuje aktuální informace ze serveru prostřednictvím HTTP požadavků. Local Data Source je lokální úložiště na zařízení implementované přes Room na Androidu nebo SwiftData na iOS. Repozitář kombinuje oba zdroje: nejprve zkontroluje lokální cache a při absenci dat požádá vzdálené API. Tato organizace práce s daty umožňuje aplikaci fungovat v offline režimu a snižuje zatížení serveru.
class UserRepository(
private val remoteDataSource: UserRemoteDataSource,
private val localDataSource: UserLocalDataSource
) {
suspend fun getUsers(): List<User> {
localDataSource.getCachedUsers()?.let { return it }
val users = remoteDataSource.fetchUsers()
localDataSource.cacheUsers(users)
return users
}
}
class UserRepository {
private let remote: UserRemoteDataSource
private let local: UserLocalDataSource
func getUsers() async throws -> [User] {
if let cached = await local.getCached() { return cached }
let users = try await remote.fetch()
await local.save(users)
return users
}
}
LRU Cache (Least Recently Used) je algoritmus cachování, kde při dosažení limitu je odstraněn prvek, který nebyl nejdéle přistupován. V mobilních aplikacích se LRU Cache používá pro obrázky, odpovědi API a serializované objekty. Správné cachování dat snižuje počet síťových požadavků a zrychluje načítání obsahu. Cache v mobilních aplikacích je nezbytnou součástí pro vysoký výkon.
Memory Cache ukládá data do RAM — přístup je extrémně rychlý, ale kapacita je omezena velikostí haldy aplikace. Disk Cache ukládá informace do souborového systému — je pomalejší, ale pojme více a přetrvává mezi relacemi. Optimální strategií v mobilním vývoji je dvouúrovňová cache: Memory Cache pro horká data a Disk Cache pro studená data. Při práci s daty se nejprve kontroluje cache první úrovně v paměti a poté cache druhé úrovně na disku.
class MemoryCache<K, V>(
private val maxSize: Int = 100
) {
private val cache = LinkedHashMap<K, V>(0, 0.75f, true)
fun get(key: K): V? = cache[key]
fun put(key: K, value: V) {
if (cache.size >= maxSize) {
cache.remove(cache.keys.first())
}
cache[key] = value
}
}
TTL cache (Time To Live) automaticky odstraní záznam po určeném časovém intervalu — vhodné pro API data. Invalidace založená na událostech vymaže cache při přijetí push oznámení o změnách. V mobilních aplikacích závisí volba strategie cachování na typu dat: obrázky se cachtují dlouho, zatímco zpravodajský kanál vyžaduje častou invalidaci. Coil na Androidu a Kingfisher na iOS již integrovaly LRU Cache pro práci s obrázky.
Offline Queue je datová struktura, která ukládá uživatelské operace (vytvoření, aktualizace, smazání) v lokální databázi, když je zařízení offline. Po obnovení připojení Sync Manager postupně aplikuje tyto operace na server. Tento typ synchronizace dat zajišťuje, že během dočasné ztráty sítě nedojde ke ztrátě žádné změny. V mobilním vývoji je Offline Queue kritickou součástí pro aplikace s nestabilním připojením.
Fronta je postavena na tabulce v Room nebo SwiftData s poli: typ operace, tělo JSON požadavku, časové razítko a stav. Sync Manager je služba na pozadí, která zpracovává čekající operace, odesílá je na server, aktualizuje stav a odstraňuje úspěšné záznamy. Synchronizace dat prostřednictvím WorkManager na Androidu nebo BGTaskScheduler na iOS pokračuje i po restartu zařízení. Použití Offline Queue spolu se správnou prací s daty zajišťuje bezproblémový uživatelský zážitek.
@Entity
data class SyncOperation(
@PrimaryKey val id: Long,
val endpoint: String,
val method: String,
val body: String,
val createdAt: Long
)
class SyncManager(
private val dao: SyncOperationDao,
private val api: ApiService
) {
suspend fun syncPending() {
dao.getPendingOperations().forEach { op ->
try {
api.execute(op.endpoint, op.method, op.body)
dao.delete(op.id)
} catch (e: Exception) {
// retry on next cycle
}
}
}
}
Exponenciální zpomalení mezi opakováními (1s, 2s, 4s, 8s) chrání server před náhlým přetížením a zabraňuje nekonečným opakováním. Limit 5 pokusů zabraňuje přetečení fronty. Synchronizace dat v mobilních aplikacích s podporou idempotence na straně serveru umožňuje bezpečná opakování a vyhýbá se duplicitám. To je zvláště důležité pro finanční transakce a objednávky.
Conflict Resolution je soubor strategií pro situace, kdy jsou stejná data upravována na různých zařízeních současně. Základní synchronizace dat vyžaduje výběr přístupu: Last-Write-Wins (vyhrává poslední zápis), verzování (vyhrává vyšší verze) nebo ruční řešení. Ve složitých scénářích se používají CRDT (Conflict-Free Replicated Data Types), které zaručují matematickou konvergenci dat.
Last-Write-Wins je nejjednodušší na implementaci, ale může ztratit uživatelské změny. Version Vector — každý záznam ukládá číslo verze a identifikátor zařízení; konflikt vzniká, když se verze neshodují. CRDT je nejspolehlivější, ale komplexní strategie: data matematicky konvergují do jediného stavu bez centralizovaného koordinátora. Synchronizace dat v mobilních aplikacích založená na CRDT se používá v kolaborativním editování v Google Docs a synchronizaci poznámek v Notion.
Při aktualizaci aplikace se mění struktura lokální databáze: přidávají se sloupce, tabulky, indexy. Schema Migration je proces transformace existující databáze na nové schéma bez ztráty dat. Room podporuje migrace prostřednictvím třídy Migration se starou a novou verzí. SwiftData používá VersionedSchema k popisu změn. Správná synchronizace dat mezi verzemi aplikace vyžaduje, aby migrace byly testovány idempotentně.
val migration1to2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE users ADD COLUMN avatar_url TEXT")
}
}
@Database(
entities = [User::class],
version = 2
)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
enum ConflictStrategy {
case lastWriteWins
case versionVector
case crdt
}
struct VersionedDocument {
let id: String
let version: Int
let data: Data
let editedBy: String
func resolve(with remote: VersionedDocument) -> VersionedDocument {
return version >= remote.version ? self : remote
}
}
Room je knihovna Google pro lokální úložiště na Androidu, postavená na SQLite a poskytující anotace pro deklarativní popis dotazů. SwiftData je framework Apple pro iOS, macOS, watchOS a visionOS, nástupce Core Data s výstižnou syntaxí Swift Macro. Oba nástroje řeší úkol práce s daty na zařízení, ale s odlišnými přístupy k organizaci kódu. Cache v mobilních aplikacích je často postavena právě na těchto technologiích.
Room používá anotace @Entity pro tabulky a @Dao pro dotazy. DAO zapouzdřuje všechny SQL operace s kontrolou v době kompilace — chyby syntaxe SQL jsou odhaleny před spuštěním. Type Converter převádí složité typy (Date, List) na primitivy SQLite. Moderní práce s daty v Android aplikacích je postavena na Room + Flow, poskytující reaktivní aktualizace UI při změnách cache nebo lokální databáze.
SwiftData používá makro @Model k definování entit a @Query k pozorování dat. Framework automaticky sleduje závislosti a aktualizuje rozhraní při změnách. Migrace schématu používá VersionedSchema popisující všechny verze. Synchronizace dat mezi SwiftData a serverem je implementována prostřednictvím vlastního Sync Manageru přihlášeného k odběru aktualizací přes @Query.
@Model
final class UserModel {
var id: String
var name: String
var email: String
var updatedAt: Date
init(id: String, name: String, email: String) {
self.id = id
self.name = name
self.email = email
self.updatedAt = Date()
}
}
| Kritérium | Room | SwiftData |
|---|---|---|
| Platforma | Android | Apple (iOS, macOS, visionOS) |
| Základ | SQLite | SQLite (zásobník Core Data) |
| Syntaxe | Kotlin anotace | Swift Macro |
| Migrace | Třída Migration | VersionedSchema |
| Reaktivita | Flow / LiveData | Property wrapper @Query |
| Multiplatformní | Pouze Android | Pouze Apple |
Často Kladené Otázky
LRU Cache je algoritmus cachování, který při dosažení limitu odstraní nejméně nedávno použitou položku. Používá se pro obrázky a API data v mobilních aplikacích.
Offline Queue ukládá uživatelské operace do lokální databáze, když není síť. Sync Manager je provede po obnovení připojení, čímž zajistí doručení změn na server.
Conflict Resolution je strategie řešení konfliktů při synchronizaci dat. Hlavní přístupy: Last-Write-Wins, Version Vector a CRDT pro distribuované systémy.
Pro Android zvolte Room — vyspělou knihovnu s kontrolou SQL v době kompilace. Pro iOS — SwiftData s deklarativní syntaxí. Pro multiplatformní projekty by byly vhodné SQLDelight nebo Realm.
Optimální synchronizace dat je při každé změně pro kritické operace a na pozadí každých 15–30 minut pro ostatní. Pro okamžité doručení použijte push oznámení.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.