SwiftUI: StateObject
SwiftUI görünümleri arasında güvenli bir şekilde veri transferi yapmamızı sağlayan StateObject property wrapper’ını keşfedin!
👋🏻 Hepinize yeniden merhaba sevgili TurkishKit okurları! Bu yazımızda sizlerle birlikte SwiftUI’ın ObservableObject
‘ini keşfediyoruz. Hadi başlayalım!
🚀 Giriş
Eğer bir süredir SwiftUI ile çalışıyorsanız, büyük ihtimalle daha önce farklı görünümler arasında veri aktarmak için ObservedObject
de kullanmışsınızdır. Eğer kullanmadıysanız da hiç sorun değil, onunla ilgili de harika bir yazımız bulunmakta. 😎
iOS 14 ve sonrasında kullanılabilen StateObject
de temelde ObservedObject
ile aynı görevi üstleniyor, ancak çok daha güvenli.
Çoğunlukla ObservedObject
işimizi mükemmel bir şekilde görse de nadiren kodumuz çökebiliyor. Bunun nedeni SwiftUI’ın görünüm struct
‘larını istediği zaman yok edip yeniden oluşturmakta özgür olması. 😳 Kulağa biraz garip gelebilir, ama aslında böyle olması oldukça mantıklı.
Bir NavigationView
düşünelim. Kullanıcı beşinci sayfaya geldiğinde SwiftUI ilk sayfayı bellek harcamamak için yok edip, kullanıcı ilk sayfaya geri döndüğünde yeniden oluşturmak isteyebilir. Çünkü sistem için bir struct
oluşturmak oldukça kolay, ama bellek alanı oldukça değerli. Sorun, ilk sayfa yok olduğunda içindeki ObservedObject
değişkenin de yok olması. Değişkenimiz yok olduğunda da uygulamamız çöküyor.
Bazı durumlarda ise struct
içerisindeki body
elemanı daha ObservedObject
değişkeni oluşturulmadan çalışıyor. Değişken daha oluşmadan body
içerisinde kullandığımızda da sonuç yine aynı. 😅
Bu durumlarda yardımımıza StateObject
koşuyor. StateObject
kullandığımızda SwiftUI bize değişkenin kesinlikle body
çalışmaya başlamadan önce yaratılacağının, ve görünüm yok edilse bile kendisinin yok edilmeyeceğinin garantisini veriyor. Böylece yukarıdaki iki kötü durum senaryosu da imkansız hale geliyor.
🔨 StateObject Kullanımı
Sanırım StateObject
‘in en iyi yanı da kullanımının neredeyse ObservedObject
ile aynı oluşu! Tek farkı değişkenimizi tanımlarken @ObservedObject
yerine @StateObject
Property Wrapper’ını kullanıyor olmamız. Merak etmeyin, aşağıda bir StateObject
oluşturmak için takip etmeniz gereken bütün adımları sıfırdan açıklıyorum. 🙂
StateObject
‘in temel amacı farklı görünümler arasında veri paylaşımı yapmak ve paylaşılan verilerde bir değişiklik olması durumunda verileri kullanan görünümlerin güncellenmesini sağlamak. Bu örnekte kullanıcı adını farklı görünümler arasında paylaşacağız. Hadi başlayalım!
İlk adım ObservableObject
protokolüne uyan bir sınıf oluşturmak — kullanıcı adını bu veri tipi içinde tutacağız. Kullanıcı imi değişkenimizin başına @Published
property wrapper’ını ekliyoruz. Bu, StateObject
değişkenini kullanan görünümlerimizin kullanıcı adı değiştiğinde kendilerini otomatik olarak güncellemelerini sağlayacak.
final class UserData: ObservableObject {
@Published var userName = ""
}
Şimdi de sıra görünümlerimizi oluşturmakta! Uygulamamız oldukça basit olacak: bir NavigationView
içinde ilk sayfada kullanıcının ismini sorulacak ve ikinci sayfada isim kullanarak bir hoşgeldin mesajı gösterilecek.
Eğer dikkat ettiyseniz her iki görünümümüzde de StateObject
yerine EnvironmentObject
kullandık. Bunu sebebi birazdanUserData
objemizi ilk defa App
objesi üzerinde oluşturup FirstView
üzerine EnvironmentObject
olarak atayacak olmamız — aynı buradaki NavigationLink
içerisinde SecondView
görünümüne yaptığımız gibi!
struct FirstView: View {
@EnvironmentObject private var userData: UserData var body: some View {
VStack {
HStack {
Text(“Lütfen isminizi girin:”)
.foregroundColor(.mint)
.font(.title3)
TextField(“İsminiz”, text: $userData.userName)
.textFieldStyle(.roundedBorder)
}
.padding() NavigationLink(
destination:
SecondView()
.environmentObject(userData)
){
Label(“Sonraki”, systemImage: “arrow.right”)
.font(.title3)
}
}
.navigationTitle(“Merhaba!”)
}
}struct SecondView: View {
@EnvironmentObject private var userData: UserData var body: some View {
Label(“Hoşgeldin, \(userData.userName)!”, systemImage: “face.smiling”)
.foregroundColor(.yellow)
.font(.title)
}
}
Şimdi de sıra biraz önce bahsettiğim gibi App sınıfında StateObject
değişkenimizi oluşturup FirstView
görünümüne environmentObject
niteleyicisini kullanarak EnvironmentObject
olarak atamak. Tabii NavigationView
objesini de unutmuyoruz. 🙂
@main
struct TurkishKit_TutorialsApp: App {
@StateObject private var userData = UserData() var body: some Scene {
WindowGroup {
NavigationView {
FirstView()
.environmentObject(userData)
}
}
}
}
İşte hepsi bu kadar! Umarım öğrendikleriniz sizin için faydalı olmuştur. Görüşmek üzere, kendinize iyi bakın. 🙂