Mobil geliştirmede, veri işleme, önbelleğe alma ve senkronizasyon, uygulamanın performansını ve güvenilirliğini belirleyen üç temel unsurdur. Google Android Architecture Guide'a göre, doğru veri işleme mimarisi yanıt hızını ve kullanıcı deneyimini doğrudan etkiler. Repository deseni, tüm veri kaynaklarına tek bir erişim noktası sağlar.
Ana Noktalar
Repository deseni, tek bir depo sınıfının tüm veri işlemlerini yönettiği, uzak REST API'lerini ve yerel depolama Room veya SwiftData'yı soyutladığı mimari bir yaklaşımdır. Veri işlemenin bu yolu, uygulamanın önce Memory Cache veya Disk Cache'ten bilgi almasını, ardından ağdan almasını sağlayarak yanıt süresini kısaltır. Mobil geliştirmede, Repository, Google ve Apple'ın önerileri sayesinde fiili standart haline gelmiştir.
Remote Data Source, HTTP istekleri aracılığıyla sunucudan güncel bilgi sağlar. Local Data Source, Android'de Room veya iOS'ta SwiftData aracılığıyla uygulanan cihazdaki yerel depolamadır. Depo, her iki kaynağı birleştirir: önce yerel önbelleği kontrol eder ve veri olmadığında uzak API'den istek yapar. Veri işlemenin bu organizasyonu, uygulamanın çevrimdışı modda çalışmasına izin verir ve sunucu yükünü azaltır.
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), sınıra ulaşıldığında en uzun süredir erişilmeyen öğenin kaldırıldığı bir önbellek algoritmasıdır. Mobil uygulamalarda, LRU Cache görseller, API yanıtları ve serileştirilmiş nesneler için kullanılır. Doğru veri önbelleğe alma, ağ isteklerinin sayısını azaltır ve içerik yüklemeyi hızlandırır. Mobil uygulamalarda önbellek, yüksek performans için gerekli bir bileşendir.
Memory Cache verileri RAM'de depolar — erişim son derece hızlıdır, ancak kapasite uygulamanın yığın boyutuyla sınırlıdır. Disk Cache bilgileri dosya sisteminde saklar — daha yavaştır ancak daha fazla tutabilir ve oturumlar arasında kalıcıdır. Mobil geliştirmede en uygun strateji iki seviyeli önbellektir: sıcak veriler için Memory Cache ve soğuk veriler için Disk Cache. Veri işlenirken, önce bellekteki birinci seviye önbellek, ardından diskteki ikinci seviye önbellek kontrol edilir.
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 önbelleği (Time To Live), belirtilen zaman aralığından sonra bir girişi otomatik olarak kaldırır — API verileri için uygundur. Olay tabanlı geçersiz kılma, değişikliklerle ilgili bir push bildirimi alındığında önbelleği temizler. Mobil uygulamalarda, önbellek stratejisi seçimi veri türüne bağlıdır: görseller uzun süre önbelleğe alınırken, haber akışı sık geçersiz kılma gerektirir. Android'de Coil ve iOS'ta Kingfisher, görsellerle çalışmak için LRU Cache'i zaten entegre etmiştir.
Offline Queue, cihaz çevrimdışıyken kullanıcı işlemlerini (oluşturma, güncelleme, silme) yerel veritabanında depolayan bir veri yapısıdır. Bağlantı geri yüklendiğinde, Sync Manager bu işlemleri sırayla sunucuya uygular. Bu tür veri senkronizasyonu, geçici ağ kaybı sırasında hiçbir değişikliğin kaybolmamasını sağlar. Mobil geliştirmede, Offline Queue dengesiz bağlantılara sahip uygulamalar için kritik bir bileşendir.
Kuyruk, Room veya SwiftData'da bir tablo üzerine inşa edilir ve alanları şunlardır: işlem türü, JSON istek gövdesi, zaman damgası ve durum. Sync Manager, bekleyen işlemleri işleyen, sunucuya gönderen, durumu güncelleyen ve başarılı girişleri kaldıran bir arka plan hizmetidir. Android'de WorkManager veya iOS'ta BGTaskScheduler aracılığıyla veri senkronizasyonu, cihaz yeniden başlatıldıktan sonra bile devam eder. Doğru veri işleme ile Offline Queue kullanımı kesintisiz bir kullanıcı deneyimi sağlar.
@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
}
}
}
}
Yeniden denemeler arasında üstel geri çekilme (1s, 2s, 4s, 8s), sunucuyu aşırı yüklenmeden korur ve sonsuz yeniden denemeleri önler. 5 deneme sınırı, kuyruk taşmasını önler. Sunucu tarafı idempotans desteği ile mobil uygulamalarda veri senkronizasyonu, yinelenenleri önleyerek güvenli yeniden denemelere izin verir. Bu, özellikle finansal işlemler ve siparişler için önemlidir.
Conflict Resolution, aynı verilerin farklı cihazlarda aynı anda değiştirildiği durumlar için bir strateji kümesidir. Temel veri senkronizasyonu bir yaklaşım seçmeyi gerektirir: Last-Write-Wins (son yazma kazanır), sürüm oluşturma (yüksek sürüm kazanır) veya manuel çözüm. Karmaşık senaryolarda, verilerin matematiksel olarak yakınsamasını garanti eden CRDT (Conflict-Free Replicated Data Types) kullanılır.
Last-Write-Wins uygulaması en basitidir ancak kullanıcı değişikliklerini kaybedebilir. Version Vector — her kayıt bir sürüm numarası ve cihaz tanımlayıcısı saklar; sürümler eşleşmediğinde çakışma oluşur. CRDT en güvenilir ancak karmaşık stratejidir: veriler merkezi bir koordinatör olmadan matematiksel olarak tek bir duruma yakınsar. CRDT tabanlı mobil uygulamalarda veri senkronizasyonu, Google Docs'ta işbirlikçi düzenleme ve Notion not senkronizasyonunda kullanılır.
Bir uygulama güncellendiğinde, yerel veritabanı yapısı değişir: sütunlar, tablolar, dizinler eklenir. Schema Migration, veri kaybı olmadan mevcut bir veritabanını yeni bir şemaya dönüştürme sürecidir. Room, eski ve yeni sürümlerle Migration sınıfı aracılığıyla geçişleri destekler. SwiftData, değişiklikleri tanımlamak için VersionedSchema kullanır. Uygulama sürümleri arasında doğru veri senkronizasyonu, geçişlerin idempotent olarak test edilmesini gerektirir.
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, Android'de yerel depolama için Google kütüphanesidir, SQLite üzerine inşa edilmiştir ve bildirimsel sorgu açıklamaları için ek açıklamalar sağlar. SwiftData, iOS, macOS, watchOS ve visionOS için Apple framework'üdür, özlü Swift Macro sözdizimi ile Core Data'nın halefidir. Her iki araç da cihazda veri işleme görevini çözer, ancak kod organizasyonu için farklı yaklaşımlarla. Mobil uygulamalarda önbellek genellikle bu teknolojiler üzerine inşa edilir.
Room, tablolar için @Entity ek açıklamalarını ve sorgular için @Dao kullanır. DAO, derleme zamanı denetimiyle tüm SQL işlemlerini kapsüller — SQL sözdizimi hataları çalışma zamanından önce tespit edilir. Type Converter, karmaşık türleri (Date, List) SQLite ilkel türlerine dönüştürür. Android uygulamalarında modern veri işleme, önbellek veya yerel veritabanı değiştiğinde reaktif UI güncellemeleri sağlayan Room + Flow etrafında inşa edilir.
SwiftData, varlıkları tanımlamak için makro @Model ve verileri gözlemlemek için @Query kullanır. Framework, bağımlılıkları otomatik olarak izler ve değişikliklerde arayüzü günceller. Şema geçişi, tüm sürümleri tanımlayan VersionedSchema kullanır. SwiftData ve sunucu arasındaki veri senkronizasyonu, @Query aracılığıyla güncellemelere abone olan özel bir Sync Manager ile uygulanır.
@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()
}
}
| Kriter | Room | SwiftData |
|---|---|---|
| Platform | Android | Apple (iOS, macOS, visionOS) |
| Temel | SQLite | SQLite (Core Data yığını) |
| Sözdizimi | Kotlin ek açıklamaları | Swift Macro |
| Geçişler | Migration sınıfı | VersionedSchema |
| Tepkisellik | Flow / LiveData | @Query property wrapper |
| Platformlararası | Sadece Android | Sadece Apple |
Sıkça Sorulan Sorular
LRU Cache, sınıra ulaşıldığında en az kullanılan öğeyi kaldıran bir önbellek algoritmasıdır. Mobil uygulamalarda görseller ve API verileri için kullanılır.
Offline Queue, ağ olmadığında kullanıcı işlemlerini yerel veritabanına kaydeder. Sync Manager, bağlantı geri yüklendiğinde bunları yürüterek değişikliklerin sunucuya iletilmesini sağlar.
Conflict Resolution, veri senkronizasyonu sırasında çakışmaları çözme stratejisidir. Ana yaklaşımlar: Dağıtık sistemler için Last-Write-Wins, Version Vector ve CRDT.
Android için Room'u seçin — derleme zamanı SQL doğrulamalı olgun bir kütüphane. iOS için — bildirimsel sözdizimi ile SwiftData. Platformlararası projeler için SQLDelight veya Realm uygun olacaktır.
Kritik işlemlerde her değişiklikte ve diğerleri için arka planda her 15–30 dakikada bir yapılan veri senkronizasyonu idealdir. Anında teslim için push bildirimleri kullanın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.