SwiftData ve CloudKit: Kendi sunucunuz olmadan eşitleme

Pek çok uygulamanın kendine ait bir sunucuya ihtiyacı yoktur. İhtiyaç duyulan şey, bir kişinin verilerini iPhone’unda, iPad’inde ve bir sonraki cihazında aynı tutmanın bir yoludur. Bu nedenle kendi uygulamalarımız ContoTrip ve Avantido için SwiftData ile CloudKit’i tercih ettik. Veriler cihazda yerel olarak durur ve kullanıcının özel iCloud veritabanı üzerinden eşitlenir. Bunun için bir veritabanı, bir API ya da bir sunucu işletmiyoruz – ve bu verilere erişimimiz de yok.

Bu yazıda neden böyle çalıştığımızı, uygulamada bunun nasıl göründüğünü ve hangi noktalarda pahalı dersler çıkarılabileceğini anlatıyoruz.

Neden kendi sunucumuz yok?

Kendi arka ucunuz, işletme sorumluluğu demektir: güncellemeler, yedeklemeler, izleme, erişim bilgileri, veri koruma belgeleri ve pek çok kişinin verisinin tek bir yerde toplanması. Bir seyahat gideri ya da yapılacaklar uygulaması için bu, Apple’ın zaten sunduğu bir işlev uğruna ödenen yüksek bir bedeldir.

CloudKit ile sorumluluk yer değiştirir. Veriler, her Apple hesabının özel veritabanında bulunur. Sağlayıcı olarak bu verileri görmeyiz; bize hiç ulaşmadıkları için korumamız da gerekmez. Bu, gizlilik politikasını sadeleştirir ve „verileriniz sizde kalır“ sözünü teknik olarak doğrulanabilir hâle getirir.

Uygulamadaki yapı

Veri modeli, SwiftData ile @Model sınıfları kullanılarak oluşturulur. Uygulama açılışta CloudKit’e yansıtılan bir kapsayıcı (container) oluşturur. Cihazda oturum açmış bir iCloud hesabı yoksa ya da iCloud uygulama için kapalıysa, uygulama tamamen yerel depolamaya geçer. Uygulama bu durumda da eksiksiz kullanılabilir; yalnızca eşitleme devre dışı kalır.

Uygulamalarımızı Swift 6 ve katı eşzamanlılık denetimiyle (strict concurrency checking) geliştiriyoruz. Projeyi XcodeGen ile bir project.yml dosyasında tanımlıyoruz; Xcode proje dosyası bundan üretilir ve asla elle düzenlenmez. Böylece yeteneklerde (capabilities) ve yetkilendirmelerde (entitlements) yapılan değişiklikler izlenebilir kalır – CloudKit söz konusu olduğunda bunlar büyük önem taşır.

Eşitlemeyi gözeten bir veri modeli

  • Tutarlar tam sayı kuruş olarak. Kayan noktalı sayılar para için uygun değildir; cihazlar arası eşitleme de bu durumu düzeltmez.
  • Değerleri kayıt anında sabitlemek. ContoTrip, döviz kurunu gider kaydedildiği anda dondurur. Böylece toplamlar, hangi cihazda ve ne zaman gösterilirse gösterilsin sabit kalır.
  • Cihaza özgü durumu modelden ayırmak. Yalnızca tek bir cihaz için geçerli olan bilgiler eşitlenen verilere ait değildir.

Uygulamada karşılaştığımız tuzaklar

iCloud kapsayıcıları silinemez

En önemli ders budur. Uygulama kimlikleri (App ID) ve uygulama grupları geliştirici portalında yeniden kaldırılabilir; iCloud kapsayıcıları ise kaldırılamaz. Adı bir kez yanlış geliştirici ekibi altında kaydederseniz – örneğin ilk test derlemesini şirket hesabı yerine kişisel bir hesapla yaparsanız – bu ad o ekipte kalıcı olarak bloke olur. Avantido’da tam olarak bu yaşandı; bu yüzden kapsayıcısı .data ekini taşıyor. O günden beri kuralımız basit: İlk cihaz derlemesi her zaman uygulamanın daha sonra yayımlanacağı ekibe karşı yapılır.

Push olmadan anlık eşitleme yok

aps-environment yetkilendirmesi eksikse CloudKit, uygulama açıldığında ve ön plana geçtiğinde eşitleme yapar. iPad’de yapılan bir değişiklik iPhone’da aynı saniyede değil, uygulama bir sonraki açılışında görünür. Zaten push kodu içermeyen uygulamalarımız için bu kabul edilebilir bir durumdur. Anlık eşitlemeye ihtiyacınız varsa „Push Notifications“ yeteneğini bilinçli olarak eklemeniz gerekir.

Gizlilik etiketi

Özel iCloud veritabanındaki veriler sağlayıcının erişimine kapalıdır ve Apple’a göre App Store’daki gizlilik etiketinde (Privacy Nutrition Label) beyan edilmeleri gerekmez. Bu gerçek bir avantajdır. Ancak diğer veri aktarımlarını dürüstçe beyan etme yükümlülüğünü ortadan kaldırmaz – örneğin bir yapay zeka işlevi içerikleri bir sağlayıcıya gönderdiğinde.

Yaklaşımın sınırları

CloudKit’in özel veritabanı, birden fazla cihazı olan tek bir kişi için tasarlanmıştır. Ortak bir hane ya da aynı veriler üzerinde çalışan bir ekip daha fazlasına ihtiyaç duyar. Biz bunu bilinçli olarak farklı çözüyoruz: Paylaşmak, birine bir şey göndermek anlamına gelir – paylaşım menüsü üzerinden dosya olarak, AirDrop, e-posta ya da bir mesajlaşma uygulamasıyla. Dosya sürümlenmiş bir biçim kullanır ve uygulaması olmayan alıcılar için okunabilir bir metin alternatifi içerir.

Ayrıca CloudKit bir Apple teknolojisidir. Bir Android uygulaması bu verilere ulaşamaz. Her iki platformda da yer alacak ürünlerde ortak nokta, ortak bir bulut değil, ortak veri değişim biçimidir.

Bu yolu ne zaman öneriyoruz?

  • Uygulama tek bir kişinin kişisel verilerini yönetiyorsa.
  • Verilerin merkezi olarak değerlendirilmesi için işe dair bir gerekçe yoksa.
  • Ürünün kullanıcı hesabı ve oturum açma olmadan çalışması isteniyorsa.
  • Gizlilik, ürün vaadinin bir parçasıysa.

Bir proje ise birden fazla kullanıcının birlikte çalışmasını, raporlamayı ya da bir web arayüzünü gerektiriyorsa, Symfony ve net tanımlanmış bir API ile ayrı bir arka uç planlıyoruz. Bu kararı en başta veriyoruz, çünkü mimariyi sonradan değiştirmek oldukça zahmetlidir.

Yukarı çık