Mobil·3 dk okuma
Flutter ile tek kod tabanından iOS ve Android: sahadan notlar
Müze Rehberim, Rezervly ve Write To Horizon'u Flutter ile geliştirirken öğrendiklerim: mimari, çevrimdışı içerik, titrek işaretçi sinyalleri, güvenli giriş ve yalnızca release'te ortaya çıkan hatalar.
Son yıllarda geliştirdiğim mobil uygulamaların çoğunu Flutter ile yazdım: müzeler için temassız sesli rehber Müze Rehberim, işletmeler için rezervasyon platformu Rezervly ve geleceğe mektup servisi Write To Horizon. Bu yazı, bu projelerden çıkan ve başka projelerde de işe yarayacağını düşündüğüm notların derlemesi.
Neden Flutter?
Flutter, iOS ve Android uygulamalarını tek bir Dart kod tabanından üretiyor ve arayüzü kendi çizim motoruyla çiziyor. Sonuç, iki platformda aynı görünen ve yerel uygulamaya yakın performans gösteren uygulamalar. Küçük ve orta ölçekli ekipler için en büyük kazanç, her özelliğin bir kez yazılıp bir kez test edilmesi.
Her proje için doğru seçim olduğunu da söyleyemem: platforma çok derinden bağlı uygulamalarda, örneğin yoğun arka plan işleri ya da özel donanım entegrasyonları gerektiğinde, yerel kod daha az sürtünme yaratabilir. Flutter bu durumlarda da platform kanallarıyla yerel koda uzanabiliyor; ama bu, işin bir kısmını iki kez yazmak demek.
Mimari: küçük ama net katmanlar
Projelerde benzer bir iskelet kullanıyorum: durum yönetimi için Riverpod, sayfa yönlendirme için go_router ve ağ istekleri için ortak bir HTTP katmanı. Ekranlar veriyi doğrudan çekmiyor, sağlayıcılar (provider) üzerinden okuyor. Bu ayrım aynı ekranı demo verisiyle göstermeyi, test etmeyi ve arka uç değiştiğinde arayüze dokunmamayı kolaylaştırıyor.
Çevrimdışı içerik: sürümlü paketler
Müzelerde mobil bağlantı çoğu zaman zayıf. Müze Rehberim'de her müzenin içeriği (metinler, görseller, sesler) sürümlü bir paket olarak indiriliyor ve cihazdan açılıyor. Panelde içerik güncellendiğinde paketin sürümü artıyor; uygulama yalnızca yeni bir sürüm olduğunda indirme yapıyor. Ziyaretçi, müzenin en kuytu salonunda bile beklemeden dinlemeye devam ediyor.
BLE işaretçileri: sinyal titrektir
Eserin yanındaki BLE işaretçisinin sinyal gücü (RSSI), insan vücudu, duvarlar ve yansımalar yüzünden saniyeden saniyeye dalgalanıyor. Ham değere göre karar veren bir uygulama, iki eser arasında sürekli gidip gelir. Çözüm, sinyali birkaç ölçüm boyunca süzmek, en yakın durağı ancak belirgin biçimde öne geçtiğinde değiştirmek ve eşik değerini her müze için ayrı ayarlanabilir kılmak. Kurulum sırasında sahada deneme yapabilmek için uygulamaya bir simülasyon modu da ekledim.
Güvenli giriş: telefon, tek kullanımlık kod ve dönen belirteçler
Rezervly'nin müşteri uygulamasında parola yok: kullanıcı telefon numarasını girip telefonuna gelen tek kullanımlık kodla (OTP) giriş yapıyor. Sunucu kısa ömürlü bir erişim belirteci (JWT) ve bir yenileme belirteci veriyor; yenileme belirteci her kullanımda yenisiyle değiştiriliyor. Böylece ele geçirilen eski bir belirteç tekrar kullanılamıyor.
Zaman: veritabanında UTC, ekranda yerel saat
Rezervasyon ve zamanlanmış teslim gibi işlerde saat hataları en sinsi hatalardır. Kural basit: sunucuda ve veritabanında bütün zamanlar UTC tutulur, yalnızca ekranda kullanıcının saat dilimine çevrilir. Write To Horizon'da SQLite'ın tarih türündeki belirsizlik yüzünden geri sayımların kaymaması için bütün tarih alanlarına açık bir dönüştürücü ekledim.
Yayın öncesi denemelerde yakalananlar
Emülatörlerde baştan sona yaptığım denemelerde, debug derlemesinde hiç görünmeyen birkaç hata yakaladım. Üçü de sık rastlanan türden:
- Release sürümü internete çıkamıyor: Flutter'ın Android şablonunda debug ve profile derlemeleri internet iznini kendi manifest dosyalarıyla ekler. Asıl (main) manifestte
INTERNETizni yoksa uygulama yalnızca release sürümünde hiçbir sunucuya bağlanamaz. Yayından önce mutlaka release derlemesini deneyin. - Boş açılan giriş ekranı: kaydırılabilir bir alanın (
SingleChildScrollView) içine konanSpacer, sınırsız yükseklikte yer kaplamaya çalıştığı için yerleşim hatası verir ve ekran boş kalır. Klavye açıldığında kayan formlarda yaygın bir tuzak. - Çalmayan sesler: Android 9 ve sonrasında şifresiz (http) bağlantılar varsayılan olarak engellenir. Medya dosyalarını HTTPS üzerinden sunmak hem bu sorunu çözer hem de güvenlik açısından doğru olandır.
Mağaza görselleri de ürünün parçası
Kullanıcı uygulamanızla ilk kez mağaza sayfasında karşılaşıyor. Gerçek ekran görüntülerinden hazırlanmış, kısa ve fayda anlatan başlıklı görseller indirme kararını doğrudan etkiliyor. Ekranları demo verisiyle doldurmak, gerçek kullanıcı bilgilerinin görünmesini de önlüyor.
Sonuç
Flutter, iyi kurulmuş bir mimariyle küçük bir ekibin iki platformda kaliteli uygulama çıkarmasını mümkün kılıyor. Asıl farkı ise çoğu zaman çatı değil ayrıntılar yaratıyor: titrek sinyaller, saat dilimleri ve yalnızca release'te ortaya çıkan hatalar. Mobil uygulama projeniz için mobil uygulama geliştirme sayfama göz atabilir ya da yazabilirsiniz.
Soner KESER — Full-Stack Yazılım Geliştirici. Mobil, masaüstü ve web uygulamaları geliştiriyor; sanal gerçeklik destekli eğitim üzerine çalışıyor. Hakkımda

