- Ağ ve veri katmanı: uygulamanın ne yapması gerekir?
- İlk adım: URLSession ile ağ isteği göndermek
- İkinci adım: Ağ istemcisini düzenli kurmak
- Üçüncü adım: Yerel saklama seçeneklerini seçmek
- Dördüncü adım: Önce yerelden göster, sonra ağdan yenile
- Sık yapılan hatalar
- Bu beceriyi Mindset programlarında nerede çalışırsınız?
- Sık sorulan sorular
Swift ile Ağ İstekleri ve Veri Saklama: URLSession'dan Çevrimdışı Akışa
URLSession ile JSON çekin, Codable ile modele çevirin, UserDefaults, Core Data, SwiftData ve Keychain arasında seçim yapıp çevrimdışı akışı kurun.
Ağ ve veri katmanı: uygulamanın ne yapması gerekir?
Çoğu iOS uygulaması sunucudan veri alma ve bu veriyi cihazda saklama işlerini birlikte yürütür. Ağ katmanı, istek göndermek, yanıtı doğrulamak ve veriyi uygulamanın anlayacağı modellere çevirmekten sorumludur. Saklama katmanı ise uygulama kapanıp açıldığında ya da bağlantı yokken veriyi hazır tutar.
İkisini birbirine karıştırmamak önemlidir. Arayüz katmanı ağın ya da diskin nasıl çalıştığını bilmemeli; yalnızca "görevleri ver" demelidir. Aradaki bir servis ya da repository katmanı, verinin yerelden mi sunucudan mı geldiğine karar verir. Bu ayrım hem testi kolaylaştırır hem de ileride saklama teknolojisini değiştirmeyi mümkün kılar.
İyi bir başlangıç tasarımı: arayüz, bir veri servisini çağırır; servis ağ istemcisini ve yerel depoyu kullanır; ağ istemcisi yalnızca iletişimle, yerel depo yalnızca saklamayla ilgilenir.
İlk adım: URLSession ile ağ isteği göndermek
Ağ iletişimi için Foundation içindeki URLSession kullanılır. Modern Swift'te eşzamansız (async/await) sürümü, geri çağırmalardan daha okunaklıdır. Önce sunucudan gelen JSON'a karşılık gelen model tanımlanır:
struct TaskItem: Codable, Identifiable { let id: String let title: String let isCompleted: Bool }
Sonra isteği ve çözümlemeyi yapan fonksiyon yazılır:
enum NetworkError: Error { case invalidResponse, serverError }
func fetchTasks() async throws -> [TaskItem] { let adres = URL(string: "https://ornek-api.example/tasks")! let (veri, yanit) = try await URLSession.shared.data(from: adres) guard let http = yanit as? HTTPURLResponse else { throw NetworkError.invalidResponse } guard http.isSuccess else { throw NetworkError.serverError } // isSuccess: durum kodunun başarılı aralıkta olduğunu söyleyen küçük yardımcı return try JSONDecoder().decode([TaskItem].self, from: veri) }
Bu fonksiyonda birkaç kontrol vardır. Yanıtın bir HTTP yanıtı olduğu doğrulanır; durum kodunun başarılı aralıkta olduğu denetlenir (başarısız yanıt veri gibi çözümlenmeye çalışılmamalıdır); ve JSONDecoder ile veri modele çevrilir. Çözümleme hatalarını sessizce yutmayın; sunucu şeması değiştiğinde ilk görülen belirti budur.
Sunucudaki alan adları Swift adlandırma biçiminden farklıysa CodingKeys ile eşlenebilir. Tarih gibi özel biçimler için çözücünün stratejileri yapılandırılır.
İkinci adım: Ağ istemcisini düzenli kurmak
Fonksiyonu doğrudan arayüzden çağırmak yerine bir ağ istemcisi arkasına alın. İstemci, taban adresi, ortak başlıkları, kimlik doğrulama belirtecini ve hata çevirisini tek yerde yönetir. Böylece her çağrıda aynı kod tekrarlanmaz.
Bazı pratik noktalar: • İptal: Kullanıcı ekrandan ayrıldığında devam eden isteği iptal edin. Eşzamansız görev iptal edildiğinde URLSession isteği de iptal edilir. • Zaman aşımı: Yapılandırmada makul bir zaman aşımı belirleyin ve kullanıcıya anlaşılır bir hata gösterin. • Hata türleri: Bağlantı yok, sunucu hatası, yetkisiz erişim ve çözümleme hatasını ayrı türlerle ifade edin; arayüz her biri için farklı mesaj gösterebilsin. • Gizli bilgiler: Erişim belirteçlerini düz metin ayarlarında değil Keychain'de saklayın. • Test: Gerçek ağa çıkmadan sınamak için istemciyi bir arayüz arkasına alın ve testte sahte istemci kullanın.
Ana iş parçacığını bloke etmemek de önemlidir: eşzamansız çağrılar bu konuda koruyucudur, ancak arayüz güncellemelerinin ana iş parçacığında yapıldığından emin olun.
Üçüncü adım: Yerel saklama seçeneklerini seçmek
Verinin türü ve karmaşıklığı seçimi belirler.
Ölçüt: UserDefaults. Uygun olduğu veri: Küçük ayarlar ve basit tercihler (tema, son seçilen sekme). Dikkat: Büyük veya hassas veri için uygun değildir.
Ölçüt: Dosyaya JSON yazmak. Uygun olduğu veri: Orta büyüklükte, kolay serileştirilebilir ve ilişkisiz veri. Dikkat: Sorgulama ve kısmi güncelleme yoktur; tüm dosya okunup yazılır.
Ölçüt: Core Data. Uygun olduğu veri: İlişkili, sorgulanması gereken, büyüyen veri kümeleri. Dikkat: Öğrenme eğrisi ve şema geçişi (migration) yönetimi gerekir.
Ölçüt: SwiftData. Uygun olduğu veri: Aynı tür veriler için Swift'e yakın modern bir yaklaşım; model sınıflarını doğrudan tanımlarsınız. Dikkat: Çerçeve yenidir; hedeflediğiniz iOS sürümünde bulunduğunu belgeden doğrulayın.
Ölçüt: Keychain. Uygun olduğu veri: Parola, erişim belirteci gibi gizli bilgiler. Dikkat: Büyük veri için değildir.
Basit bir kural: ayarlar için UserDefaults, gizli bilgi için Keychain, yapılandırılmış ve sorgulanan veri için Core Data ya da SwiftData. Önce ihtiyacınız olan en basit seçeneği seçin; veri ilişkili ve büyük hale geldiğinde taşırsınız.
Dördüncü adım: Önce yerelden göster, sonra ağdan yenile
Kullanıcı deneyimini belirleyen şey, ağ yavaşken ya da yokken ekranın ne gösterdiğidir. Yaygın model "önce yerel, sonra ağ"dır: ekran açıldığında yerel depodaki veri hemen gösterilir, arka planda ağdan güncel veri çekilir, geldiğinde yerel depo güncellenir ve arayüz yenilenir.
Bu akışı veri servisi yönetir:
func tasks() async throws -> [TaskItem] { let yerel = try yerelDepo.hepsiniOku() Task { await yenile() } // ağdan güncelle, depoyu ve arayüzü besle return yerel }
func yenile() async { guard let guncel = try? await agIstemcisi.fetchTasks() else { return } try? yerelDepo.degistir(guncel) }
Dikkat edilecek noktalar: yenileme sırasında hata olursa mevcut yerel veriyi bozmayın; kullanıcıya veri yenilenemedi bilgisi verin. Çakışma durumunda (kullanıcı çevrimdışı düzenleme yaptı, sunucu da değişti) hangi tarafın kazanacağına dair kural önceden belirlenmelidir. Yerel veri sunucudan hangi sürede eski sayılır, hangi zamanda yeniden çekilir gibi geçerlilik politikaları da ürünün ihtiyacına göre tanımlanır.
Bu servis katmanı, bir Repository yaklaşımıyla birebir örtüşür: arayüz yalnızca servisi bilir, verinin kaynağı gizlidir.
Sık yapılan hatalar
- Ağ çağrısını doğrudan görünümde yazmak: Test edilemez ve yeniden kullanılamaz kod üretir.
- Durum kodunu kontrol etmemek: Hatalı yanıtı veri gibi çözmeye çalışmak anlaşılmaz hatalar doğurur.
- Çözümleme hatasını yutmak: Sunucu şeması değiştiğinde sessizce boş liste göstermek sorunu gizler.
- Hassas veriyi UserDefaults'ta saklamak: Erişim belirteci ve parola için Keychain kullanılmalıdır.
- Şema değişikliğini planlamamak: Yerel model değiştiğinde eski veriyi taşıyan bir geçiş stratejisi yoksa güncelleme sonrası uygulama çöker.
- Ana iş parçacığında ağır disk işi yapmak: Büyük okuma ve yazma işlemlerini arka planda yapın.
- Çevrimdışı durumu hiç düşünmemek: Bağlantı yokken boş ekran yerine yerel veriyi ve anlaşılır bir bilgi göstermek gerekir.
- Her şey için tek bir çözüm kullanmak: Ayar, gizli bilgi ve ilişkili veri için farklı depolar daha doğrudur.
Bu beceriyi Mindset programlarında nerede çalışırsınız?
iOS Uygulama Geliştirme (Swift) Temelleri programı, veri kalıcılığı ve ağ katmanı için ayrı bir modül ayırır; Swift ile İleri Seviye iOS Geliştirme (SwiftUI) programı ise modern eşzamanlılık ve ağ katmanı ile mimari ve test edilebilirlik konularını daha derin biçimde işler.
Bu içerik, sunucu ile konuşan ve çevrimdışı çalışabilmesi gereken kurumsal mobil uygulamalar geliştiren ekipler için uygundur. Arka uç ve mobil geliştiricilerin ağ sözleşmesi, hata yönetimi ve önbellek politikaları üzerinde ortak çalışması, uygulamanın dayanıklılığını belirgin biçimde artırır.
İlgili Mindset programı
iOS Uygulama Geliştirme (Swift) Temelleri
Sık sorulan sorular
URLSession ile JSON verisi nasıl çekilir ve modele çevrilir?
URLSession'ın eşzamansız data metodu ile adresi çağırırsınız; yanıtın bir HTTP yanıtı olduğunu ve durum kodunun başarılı aralıkta olduğunu kontrol edersiniz. Sonra JSONDecoder ile veriyi Codable uyumlu bir modele çevirirsiniz. Çözümleme hatalarını yutmayın, sunucu şeması değiştiğinde ilk belirti bu hatadır.
UserDefaults, Core Data ve SwiftData arasında nasıl seçim yaparım?
UserDefaults küçük ayarlar ve basit tercihler içindir. Core Data ve SwiftData, ilişkili, sorgulanan ve büyüyen veri kümelerini saklar; SwiftData daha yeni ve Swift'e yakın bir yaklaşımdır ve hedef iOS sürümünüzde bulunması gerekir. Parola ve erişim belirteci için bunların hiçbiri değil, Keychain kullanılmalıdır.
Çevrimdışı çalışan bir iOS uygulaması nasıl kurulur?
Önce yerel depodaki veriyi gösterin, arka planda ağdan güncel veriyi çekip depoyu ve arayüzü yenileyin. Yenileme hatasında mevcut veriyi bozmayın, kullanıcıya bilgi verin. Çevrimdışı düzenlemeler için çakışma kuralı ve verinin ne zaman eski sayılacağına dair politika baştan belirlenmelidir.
Erişim belirtecini nerede saklamalıyım?
Keychain'de. UserDefaults düz biçimde saklar ve gizli bilgi için uygun değildir. Keychain, hassas verileri sistem tarafından korunan bir alanda tutar. Belirteci istemci koduna gömmeyin; oturum açıldığında alın, Keychain'e yazın ve çıkış yapıldığında silin.
Core Data modelini değiştirirsem eski veriye ne olur?
Şema değiştiğinde eski veriyi yeni modele taşıyan bir geçiş (migration) stratejisi tanımlanmazsa uygulama güncellemeden sonra veriyi açamayabilir. Basit değişiklikler için çerçevenin otomatik geçiş desteğinden yararlanılabilir; karmaşık değişikliklerde açık bir geçiş planı yazıp güncelleme öncesi eski sürümden gelen veriyle test etmek gerekir.
İlgili rehberler
İlgili eğitimler
Kategori: Yazılım Geliştirme