@EnvironmentObject — SwiftUI-də property wrapper-dır ki, iyerarxiyada istənilən View-ə ObservableObject-ə initiatorlar zənciri vasitəsilə açıq ötürmədən giriş imkanı verir. Obyekt .environmentObject() modifieri vasitəsilə müəyyən iyerarxiya səviyyəsində mühitə inject edilir, bundan sonra bütün uşaq View-lər onu @EnvironmentObject vasitəsilə əldə edə bilər. Bu, obyekti istifadə etməyən ara View-lər vasitəsilə ötürmək zərurətini aradan qaldırır — prop drilling deyilən problem. John Sundell — Swift by Sundell (2025) məqaləsinə görə, @EnvironmentObject xüsusilə ekranlararası məlumatlar üçün faydalıdır: istifadəçi sessiyası, tətbiq parametrləri, alış-veriş səbəti meneceri və ya yerli məlumat keşi.
Əsas məqamlar
@EnvironmentObject — SwiftUI View-ə tətbiqin mühitindən (environment) ObservableObject-ə giriş imkanı verən property wrapper-dır. Mühit — .environmentObject() modifieri vasitəsilə View iyerarxiyasının istənilən səviyyəsində obyektləri yerləşdirə biləcəyiniz konteynerdir. Obyekt mühitə yerləşdirildikdən sonra istənilən uşaq View onu sadəcə @EnvironmentObject ilə xassə elan edərək və obyekt tipini göstərərək əldə edə bilər.
@EnvironmentObject-in əsas vəzifəsi — obyekti hər bir ara səviyyədən ötürmək məcburiyyəti olmadan dərin View iyerarxiyası vasitəsilə məlumat ötürmə problemini həll etməkdir. NavigationStack, TabView və modal pəncərələrin şaxələnmiş strukturu olan mürəkkəb tətbiqlərdə @EnvironmentObject boilerplate kodu aradan qaldıraraq arxitekturanı əhəmiyyətli dərəcədə sadələşdirir.
Apple Developer Documentation — Environment (2025)-ə görə, @EnvironmentObject PreferenceKey və View identifikasiyasına əsaslanan SwiftUI daxili mexanizmindən istifadə edir. Hər View öz mühitinə istinad saxlayır, bu da valideyn View-dən miras alınır və .environmentObject() vasitəsilə genişləndirilə bilər. Obyektin axtarışı iyerarxiyada yuxarıya doğru kökə qədər aparılır.
class UserSession: ObservableObject {
@Published var isLoggedIn = false
@Published var userName: String = ""
func login(name: String) {
userName = name
isLoggedIn = true
}
}
@main
struct MyApp: App {
@StateObject var session = UserSession()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(session)
}
}
}
@EnvironmentObject SwiftUI-də quraşdırılmış asılılıq inject etmə (DI) mexanizmi əsasında işləyir. View-də .environmentObject() çağırdıqda, SwiftUI obyekti bu View və onun bütün nəsli ilə əlaqəli xüsusi anbarda saxlayır. Uşaq View eyni tipdə @EnvironmentObject elan etdikdə, SwiftUI valideyn iyerarxiyası ilə yuxarı qalxaraq obyekti mühitdə axtarır.
Əhəmiyyətli xüsusiyyət — obyektin tipi mühitdə axtarış üçün açar kimi istifadə olunur. Əgər mühitdə eyni tipli iki obyekt varsa, SwiftUI cari View-ə iyerarxiyada ən yaxın olanı tapacaq. Obyektin WindowGroup səviyyəsində inject edilməsi onu tətbiqin bütün ekranları üçün qlobal olaraq əlçatan edir ki, bu da ümumi təyinatlı xidmətlər üçün əlverişlidir.
objc.io — SwiftUI Architecture (2025)-ə görə, daxili olaraq @EnvironmentObject @ObservedObject-ə bənzər mexanizmdən istifadə edir, lakin iyerarxiyada obyektin axtarışı üçün əlavə abstraksiya səviyyəsi ilə. SwiftUI obyekti kopyalamır və yaratmır — mövcud instansiyaya istinad ötürür, buna görə də obyektdəki dəyişikliklər @EnvironmentObject istifadə edən bütün View-lər üçün avtomatik görünür.
Həm @EnvironmentObject, həm də @ObservedObject eyni əsas funksiyanı yerinə yetirir — View-ləri ObservableObject dəyişikliklərinə abunə edir. Fərq obyektin ötürülmə mexanizmindədir. @ObservedObject initiator vasitəsilə açıq ötürmə tələb edir, @EnvironmentObject isə hər bir ara View-də açıq göstərmədən obyekti mühitdən əldə edir.
| Xüsusiyyət | @EnvironmentObject | @ObservedObject |
|---|---|---|
| Ötürmə | İyerarxiya səviyyəsində .environmentObject() vasitəsilə | Hər View-in initiatoru vasitəsilə |
| Asılılıqların aşkarlığı | Gizli — View imzasında görünmür | Aşkar — View init-də görünür |
| Ara View-lər | Obyekt haqqında bilmir | Obyekti irəli ötürməlidir |
| Xəta riski | Obyekt olmadıqda runtime crash | Kompilyasiya vaxtı yoxlaması (parametr məcburidirsə) |
| Prop drilling | Aradan qaldırır | Əl ilə ötürmə tələb edir |
@EnvironmentObject və @ObservedObject arasında seçim arxitekturadan asılıdır. Obyekt iyerarxiyada dərində və çoxlu ekranlara lazımdırsa — @EnvironmentObject daha rahatdır. Arxitektura test etmə və oxunaqlılıq üçün asılılıqların açıq göstərilməsini tələb edirsə — @ObservedObject üstünlük təşkil edir.
Ən çox yayılmış ssenari — tətbiqin bütün ekranlarında əlçatan olmalı olan istifadəçi sessiyası. UserSession-i .environmentObject() vasitəsilə tətbiqin kökündə inject edərək, istənilən ekran istifadəçi məlumatlarına və autorizasiya statusuna giriş əldə edə bilər.
struct ProfileView: View {
@EnvironmentObject var session: UserSession
var body: some View {
VStack {
if session.isLoggedIn {
Text("Salam, \(session.userName)")
Button("Çıxış") {
session.isLoggedIn = false
}
} else {
LoginView()
}
}
}
}
struct SettingsView: View {
@EnvironmentObject var session: UserSession
var body: some View {
Form {
Text("Kimi daxil olmusunuz: \(session.userName)")
}
}
}
Diqqət yetirin: nə ProfileView, nə də SettingsView session-u initiator vasitəsilə almır. Onlar sadəcə @EnvironmentObject var session: UserSession elan edir və SwiftUI avtomatik olaraq obyekti mühitdə tapır. Bu, mövcud məlumat ötürmə kodunu dəyişmədən yeni ekranlar əlavə etməyə imkan verir.
@EnvironmentObject-in əsas riski — obyekt mühitə inject edilməyibsə runtime crash-dır. Opsional parametrlərdən fərqli olaraq, @EnvironmentObject nil ola bilməz. @EnvironmentObject ilə View ekranda görünərsə və valideyn View bu tip üçün .environmentObject() çağırmayıbsa, tətbiq dərhal "Fatal error: No ObservableObject of type X found" xətası ilə çökür.
İyerarxiyanın müxtəlif səviyyələrində eyni tipli iki obyekt inject etsəniz, uşaq View iyerarxiyada ən yaxın olanı alacaq. Bu, qarışıqlığa səbəb ola bilər, əgər developer kök mühitdəki obyektin eyni tipli öz mühiti olan modal pəncərədə əlçatan olacağını gözləyirsə.
SwiftUI-nin inkişafı ilə @EnvironmentObject-in bəzi çatışmazlıqlarını həll edən alternativ asılılıq idarəetmə üsulları meydana çıxdı — ilk növbədə asılılıqların qeyri-aşkarlığı və runtime crash riski.
Yanaşma seçimi komandanın ölçüsündən və tətbiqin mürəkkəbliyindən asılıdır. Kiçik layihələr üçün @EnvironmentObject mükəmməl işləyir. Onlarla ekranı və test etməyə ciddi tələbləri olan böyük layihələr üçün @ObservedObject vasitəsilə açıq ötürmə və ya DI konteyneri üstünlük təşkil edir.
Tez-tez verilən suallar
Bəli, View müxtəlif tipli istənilən sayda @EnvironmentObject elan edə bilər. SwiftUI hər tipi mühitdə müstəqil axtarır. Bu, View-in eyni anda istifadəçi sessiyasına, parametrlərə və alış-veriş səbətinə girişə ehtiyacı olduqda rahatdır — hər obyekt ayrıca inject edilir.
Preview View-i göstərməyə çalışarkən runtime error ilə çökəcək. @EnvironmentObject istifadə edən View-lər üçün Preview-də həmişə .environmentObject() əlavə edin. Preview-in düzgün işləməsi və realistik vəziyyəti göstərməsi üçün test məlumatları ilə mock obyektlərdən istifadə edin.
Xeyr, @EnvironmentObject yalnız ObservableObject-ə uyğun olan konkret sinif tipləri ilə işləyir. Protokollar üçün type erasure və ya sarğıcıdan istifadə etməlisiniz: protokol tipli obyektə istinad saxlayan sarğıcı sinif yaradın və sarğıcını @EnvironmentObject vasitəsilə inject edin.
Test məlumatları ilə ObservableObject nümunəsi yaradın və onu View-ə .environmentObject(testObject) vasitəsilə testdə ötürün. Bu, SwiftUI UI testi üçün standart nümunədir. Vahid testlər üçün məntiqi ObservableObject-də izolyasiya edin və onu View-dən ayrı test edin.
@EnvironmentObject əlavə performans yükü yaratmır, çünki o, obyekti yalnız istinad olaraq ötürür, kopyalamır. Lakin qlobal obyektdə @Published xassələrinin tez-tez yenilənməsi eyni anda çoxlu View-in yenidən çəkilməsinə səbəb ola bilər ki, bu da performansa təsir göstərə bilər.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun