Flutter ve Dart ile Çevrimdışı Çalışan Mobil Uygulamalar
İki kişisel mobil projede, internet yokken de eksiksiz çalışan uygulamalar.
Mert Celal Yılmaz · Full Stack Developer · Güncellendi:
Web tarafında Angular kullanırken mobil uygulamalarda tercihim Flutter. Flutter, Google'ın geliştirdiği ve tek bir kod tabanından hem Android hem iOS için uygulama çıkarmayı sağlayan bir arayüz framework'ü; Dart ise onun dili. Arayüzü platformun hazır bileşenleriyle değil kendi çizim motoruyla çiziyor, bu yüzden bir ekran her cihazda aynı görünüyor. Geliştirirken hot reload sayesinde yaptığın değişikliği saniyeler içinde görüyorsun, yayın derlemesinde ise Dart kodu doğrudan makine koduna derleniyor.
Flutter'ı iki kişisel mobil projemde kullandım. Bütçem, sunucusu ve hesabı olmayan, tamamen çevrimdışı çalışan bir gelir-gider ve bütçe takip uygulaması; tüm veri telefondaki tek bir SQLite dosyasında duruyor. Harfsayı ise kelime ve işlem turlarını birleştiren, arkadaşlarla canlı yarışılabilen bir Türkçe mobil oyun; arkasında .NET 10 ve SignalR ile çalışan bir sunucu var ama internetsiz de oynanabiliyor. İki projede de durum yönetimi için Riverpod'u, yerel veritabanı için Drift'i kullandım.
Çevrimdışı çalışmak, veriyi telefonda doğru modellemeyi zorunlu kılıyor. Bütçem'de tutarlar kuruş cinsinden tam sayı olarak saklanıyor ve her hareket çift kayıtlı bir posting modeliyle tutuluyor; kayan noktalı sayılarla tutulan bir bakiye er ya da geç kuruş farkı üretir. Kalite tarafında da testsiz ilerlemedim: Bütçem'de saf servisleri, veritabanı göçlerini ve uçtan uca ekran akışlarını kapsayan 794 test var; ekran başına sorgu bütçesini denetleyen testler ve 10.000 kayıtla koşan bir performans testi de bunların arasında.
Kullanıcının verisi yalnızca kendi telefonunda duruyorsa, o verinin doğruluğu tamamen senin kodunun sorumluluğunda.
Drift, tabloları Dart sınıfları olarak tanımlamanı ve tip güvenli sorgu kodunu build_runner ile önceden ürettirmeni sağlıyor; bir sorguyu watch ile dinlediğinde, ilgili tabloya kayıt eklendiği anda yeni sonuç akışa düşüyor. Bu akışı bir Riverpod provider'ına bağlamak, veri değiştiğinde yalnızca o veriye bağlı widget'ların yeniden çizilmesi demek. Toplam bakiye gibi hesapları da Dart tarafında listeyi tek tek dolaşarak değil, tek bir SQL sorgusunda veritabanına yaptırıyorum; kayıt sayısı büyüdükçe farkı hissettiren şey bu.
Flutter'ın tek kod tabanı vaadi her şeyi kapsamıyor. Bütçem'in ana ekran widget'ı ve uygulamanın kendini güncelleyebilmesi için gereken kurulum adımı Flutter'ın içinde çözülmüyor; ikisi için de Kotlin tarafında native kod yazmam gerekti. Uygulamayı mağaza yerine imzalı APK olarak dağıtmak güncellemeyi de senin sorunun yapıyor; version.json üzerinden çalışan kendi kendini güncelleme mekanizması bu yüzden var. Çevrimdışı çalışmanın bir bedeli de senkronizasyon: Harfsayı'da internetsiz oynanan sonuçların sunucuya iki kez yazılmaması için senkronu cihaz UUID'siyle idempotent kurmak gerekti.