Cache a synchronizace dat v mobilním vývoji: co to je, jaké strategie a jak to funguje

Autor: IT Sectr Publikováno: 2026-06-19 Doba čtení: 12 min

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

  • Repository — jediný zdroj dat skrývající detaily implementace Remote a Local Data Source
  • LRU Cache — algoritmus cachování, který při dosažení limitu odstraňuje nejméně nedávno použité položky
  • Offline Queue — mechanismus odloženého provádění operací, když je zařízení offline
  • Conflict Resolution — strategie řešení konfliktů při synchronizaci mezi více zařízeními
  • Schema Migration — proces bezpečné změny struktury lokální databáze bez ztráty dat

Práce s Daty v Mobilních Aplikacích: Vzor Repository a Data Source

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 a Local Data Source

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.

Příklad Repository v Kotlin

kotlin
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
    }
}

Příklad Repository v Swift

swift
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
    }
}

Cachování Dat: LRU Cache, Disk Cache a Memory Cache

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 vs Disk Cache

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.

Příklad Implementace LRU Cache

kotlin
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
    }
}

Strategie Invalidace Cache

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 Fronta: Offline Queue a Sync Manager

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.

Architektura Offline Queue

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.

Příklad Offline Queue v Kotlin

kotlin
@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
            }
        }
    }
}

Zásady Opakování a Časové Limity

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.

Synchronizace Dat: Conflict Resolution a Schema Migration

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.

Strategie Řešení Konfliktů

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.

Schema Migration: Bezpečná Aktualizace Databáze

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ě.

Příklad Schema Migration v Room

kotlin
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
}

Příklad Conflict Resolution v Swift

swift
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 a SwiftData pro Lokální Úložiště

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: DAO, Entities a Type Converters

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: @Model a @Query

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.

Příklad Modelu v SwiftData

swift
@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()
    }
}

Srovnání Room vs SwiftData

KritériumRoomSwiftData
PlatformaAndroidApple (iOS, macOS, visionOS)
ZákladSQLiteSQLite (zásobník Core Data)
SyntaxeKotlin anotaceSwift Macro
MigraceTřída MigrationVersionedSchema
ReaktivitaFlow / LiveDataProperty wrapper @Query
MultiplatformníPouze AndroidPouze Apple

Často Kladené Otázky

Co je LRU Cache?

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.

Jak funguje Offline Queue?

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.

Co je Conflict Resolution?

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.

Room nebo SwiftData — co vybrat?

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.

Jak často provádět synchronizaci?

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í

  • Repository kombinuje Remote a Local Data Source a poskytuje jediný přístupový bod při práci s daty
  • LRU Cache s dvouúrovňovým systémem Memory + Disk Cache snižuje síťové požadavky a zrychluje načítání obsahu
  • Offline Queue se Sync Managerem zaručuje doručení změn při dočasné ztrátě připojení
  • Conflict Resolution založený na Version Vector nebo CRDT zabraňuje ztrátě dat při paralelní synchronizaci
  • Schema Migration zajišťuje bezpečné aktualizace lokální databáze bez ztráty uživatelských dat
  • Room s DAO a SwiftData s @Model jsou standardní řešení pro lokální úložiště v mobilním vývoji
  • Komplexní přístup k cachování a synchronizaci dat je základem výkonné mobilní aplikace

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í.

Prodiskutovat projekt