Keš i sinhronizacija podataka u mobilnom razvoju: šta je to, koje strategije i kako funkcioniše

Аутор: IT Sectr Објављено: 2026-06-19 Време читања: 12 мин

U mobilnom razvoju, rad sa podacima, keširanje i sinhronizacija su tri ključna aspekta koji određuju performanse i pouzdanost aplikacije. Prema Google Android Architecture Guide, pravilna arhitektura obrade podataka direktno utiče na brzinu odgovora i korisničko iskustvo. Repository obrazac obezbeđuje jedinstvenu tačku pristupa svim izvorima podataka.

Ključne Tačke

  • Repository — jedinstveni izvor podataka koji skriva detalje implementacije Remote i Local Data Source
  • LRU Cache — algoritam keširanja koji uklanja najmanje skoro korišćene elemente kada se dostigne limit
  • Offline Queue — mehanizam odloženog izvršavanja operacija kada je uređaj bez mreže
  • Conflict Resolution — strategija rešavanja sukoba prilikom sinhronizacije između više uređaja
  • Schema Migration — proces bezbedne promene strukture lokalne baze podataka bez gubitka informacija

Rad sa podacima u mobilnim aplikacijama: Repository obrazac i Data Source

Repository obrazac je arhitektonski pristup u kojem jedna repozitorijumska klasa upravlja svim operacijama sa podacima, apstrahujući udaljene REST API-je i lokalno skladištenje Room ili SwiftData. Ovakav način rada sa podacima omogućava aplikaciji da prvo dobije informacije iz Memory Cache ili Disk Cache, a zatim iz mreže, smanjujući vreme odgovora. U mobilnom razvoju, Repository je postao de facto standard zahvaljujući preporukama Google-a i Apple-a.

Remote Data Source i Local Data Source

Remote Data Source pruža ažurne informacije sa servera putem HTTP zahteva. Local Data Source je lokalno skladište na uređaju, implementirano kroz Room na Androidu ili SwiftData na iOS-u. Repozitorijum kombinuje oba izvora: prvo proverava lokalni keš, a kada nema podataka, zahteva od udaljenog API-ja. Ovakva organizacija rada sa podacima omogućava aplikaciji da funkcioniše u offline režimu i smanjuje opterećenje servera.

Primer Repository u 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
    }
}

Primer Repository u 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
    }
}

Keširanje podataka: LRU Cache, Disk Cache i Memory Cache

LRU Cache (Least Recently Used) je algoritam keširanja gde se, kada se dostigne limit, uklanja element kojem se najduže nije pristupalo. U mobilnim aplikacijama, LRU Cache se koristi za slike, API odgovore i serijalizovane objekte. Pravilno keširanje podataka smanjuje broj mrežnih zahteva i ubrzava učitavanje sadržaja. Keš u mobilnim aplikacijama je neophodna komponenta za visoke performanse.

Memory Cache vs Disk Cache

Memory Cache čuva podatke u RAM-u — pristup je izuzetno brz, ali kapacitet je ograničen veličinom heap-a aplikacije. Disk Cache čuva informacije na datotečnom sistemu — sporiji je, ali može da primi više i traje između sesija. Optimalna strategija u mobilnom razvoju je dvoslojni keš: Memory Cache za vruće podatke i Disk Cache za hladne podatke. Prilikom rada sa podacima, prvo se proverava keš prvog nivoa u memoriji, zatim keš drugog nivoa na disku.

Primer implementacije 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
    }
}

Strategije validacije keša

TTL keš (Time To Live) automatski uklanja unos nakon određenog vremenskog intervala — pogodno za API podatke. Validacija zasnovana na događajima čisti keš po prijemu push obaveštenja o promenama. U mobilnim aplikacijama, izbor strategije keširanja zavisi od tipa podataka: slike se keširaju dugo, dok novinski feed zahteva čestu validaciju. Coil na Androidu i Kingfisher na iOS-u su već ugradili LRU Cache za rad sa slikama.

Offline red: Offline Queue i Sync Manager

Offline Queue je struktura podataka koja čuva korisničke operacije (kreiranje, ažuriranje, brisanje) u lokalnoj bazi podataka kada je uređaj offline. Kada se veza uspostavi, Sync Manager sekvencijalno primenjuje ove operacije na server. Ova vrsta sinhronizacije podataka garantuje da nijedna promena neće biti izgubljena tokom privremenog gubitka mreže. U mobilnom razvoju, Offline Queue je kritična komponenta za aplikacije sa nestabilnom vezom.

Arhitektura Offline Queue

Red se gradi na tabeli u Room ili SwiftData sa poljima: tip operacije, JSON telo zahteva, vremenska oznaka i status. Sync Manager je pozadinski servis koji obrađuje operacije na čekanju, šalje ih serveru, ažurira status i uklanja uspešne unose. Sinhronizacija podataka putem WorkManager na Androidu ili BGTaskScheduler na iOS-u nastavlja se čak i nakon ponovnog pokretanja uređaja. Korišćenje Offline Queue zajedno sa pravilnim radom sa podacima obezbeđuje besprekorno korisničko iskustvo.

Primer Offline Queue u 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
            }
        }
    }
}

Politika ponovnih pokušaja i tajmauti

Eksponencijalno kašnjenje između ponovnih pokušaja (1s, 2s, 4s, 8s) štiti server od naglog opterećenja i sprečava beskonačne pokušaje. Limit od 5 pokušaja sprečava prelivanje reda. Sinhronizacija podataka u mobilnim aplikacijama sa podrškom za idempotentnost na serverskoj strani omogućava bezbedne ponovne pokušaje, izbegavajući duplikate. Ovo je posebno važno za finansijske transakcije i porudžbine.

Sinhronizacija podataka: Conflict Resolution i Schema Migration

Conflict Resolution je skup strategija za situacije kada se isti podaci menjaju na različitim uređajima istovremeno. Osnovna sinhronizacija podataka zahteva izbor pristupa: Last-Write-Wins (poslednji zapis pobednik), verzionisanje (viša verzija pobednik) ili ručno rešavanje. U složenim scenarijima koriste se CRDT (Conflict-Free Replicated Data Types) koji garantuju matematičku konvergenciju podataka.

Strategije rešavanja sukoba

Last-Write-Wins je najjednostavniji za implementaciju, ali može izgubiti korisničke promene. Version Vector — svaki zapis čuva broj verzije i identifikator uređaja; sukob nastaje kada se verzije ne poklapaju. CRDT je najpouzdanija, ali složena strategija: podaci matematički konvergiraju ka jedinstvenom stanju bez centralizovanog koordinatora. Sinhronizacija podataka u mobilnim aplikacijama zasnovana na CRDT-u koristi se u kolaborativnom uređivanju u Google Docs-u i sinhronizaciji beleški u Notion-u.

Schema Migration: bezbedno ažuriranje baze

Kada se aplikacija ažurira, struktura lokalne baze podataka se menja: dodaju se kolone, tabele, indeksi. Schema Migration je proces transformacije postojeće baze u novu šemu bez gubitka podataka. Room podržava migracije kroz klasu Migration sa starom i novom verzijom. SwiftData koristi VersionedSchema za opisivanje promena. Pravilna sinhronizacija podataka između verzija aplikacije zahteva da migracije budu testirane idempotentno.

Primer Schema Migration u 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
}

Primer Conflict Resolution u 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 i SwiftData za lokalno skladištenje

Room je Google biblioteka za lokalno skladištenje na Androidu, izgrađena na SQLite i pruža anotacije za deklarativni opis upita. SwiftData je Apple frejmvork za iOS, macOS, watchOS i visionOS, naslednik Core Data sa sažetom Swift Macro sintaksom. Oba alata rešavaju zadatak rada sa podacima na uređaju, ali sa različitim pristupima organizaciji koda. Keš u mobilnim aplikacijama se često gradi upravo na ovim tehnologijama.

Room: DAO, Entities i Type Converters

Room koristi anotacije @Entity za tabele i @Dao za upite. DAO enkapsulira sve SQL operacije sa proverom u vreme kompilacije — SQL sintaksne greške se otkrivaju pre izvršavanja. Type Converter pretvara složene tipove (Date, List) u SQLite primitive. Savremeni rad sa podacima u Android aplikacijama gradi se oko Room + Flow, obezbeđujući reaktivno ažuriranje UI pri promenama u kešu ili lokalnoj bazi.

SwiftData: @Model i @Query

SwiftData koristi makro @Model za definisanje entiteta i @Query za posmatranje podataka. Frejmvork automatski prati zavisnosti i ažurira interfejs pri promenama. Migracija šeme koristi VersionedSchema koja opisuje sve verzije. Sinhronizacija podataka između SwiftData i servera implementira se kroz prilagođeni Sync Manager koji se pretplaćuje na ažuriranja putem @Query.

Primer modela u 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()
    }
}

Poređenje Room vs SwiftData

KriterijumRoomSwiftData
PlatformaAndroidApple (iOS, macOS, visionOS)
OsnovaSQLiteSQLite (Core Data stek)
SintaksaKotlin anotacijeSwift Macro
MigracijeMigration klasaVersionedSchema
ReaktivnostFlow / LiveData@Query property wrapper
VišeplatformskiSamo AndroidSamo Apple

Često postavljana pitanja

Šta je LRU Cache?

LRU Cache je algoritam keširanja koji, kada se dostigne limit, uklanja najmanje skoro korišćeni element. Koristi se za slike i API podatke u mobilnim aplikacijama.

Kako funkcioniše Offline Queue?

Offline Queue čuva korisničke operacije u lokalnoj bazi podataka kada nema mreže. Sync Manager ih izvršava kada se veza uspostavi, garantujući dostavu promena serveru.

Šta je Conflict Resolution?

Conflict Resolution je strategija rešavanja sukoba prilikom sinhronizacije podataka. Glavni pristupi: Last-Write-Wins, Version Vector i CRDT za distribuirane sisteme.

Room ili SwiftData — šta izabrati?

Za Android izaberite Room — zrelu biblioteku sa SQL proverom u vreme kompilacije. Za iOS — SwiftData sa deklarativnom sintaksom. Za višeplatformske projekte, SQLDelight ili Realm bi bili odgovarajući.

Koliko često vršiti sinhronizaciju?

Optimalna sinhronizacija podataka je pri svakoj promeni za kritične operacije i u pozadini svakih 15–30 minuta za ostale. Koristite push obaveštenja za trenutnu dostavu.

Rezime

  • Repository kombinuje Remote i Local Data Source, obezbeđujući jedinstvenu tačku pristupa pri radu sa podacima
  • LRU Cache sa dvoslojnim sistemom Memory + Disk Cache smanjuje mrežne zahteve i ubrzava učitavanje sadržaja
  • Offline Queue sa Sync Manager garantuje dostavu promena pri privremenom gubitku veze
  • Conflict Resolution zasnovan na Version Vector ili CRDT sprečava gubitak podataka pri paralelnoj sinhronizaciji
  • Schema Migration obezbeđuje bezbedno ažuriranje lokalne baze bez gubitka korisničkih informacija
  • Room sa DAO i SwiftData sa @Model su standardna rešenja za lokalno skladištenje u mobilnom razvoju
  • Integralni pristup keširanju i sinhronizaciji podataka je osnova performantne mobilne aplikacije

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту