@EnvironmentObject: bu nədir, asılılıqların inject edilməsi və məlumatlara giriş

Müəllif: IT Sectr Dərc olunub: 2026-06-26 Oxuma vaxtı: 9 dəq

@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 mühitindən ObservableObject-ə giriş üçün property wrapper.
  • .environmentObject() vasitəsilə inject — obyekt iyerarxiyaya bir dəfə ötürülür, bütün uşaq View-lər üçün əlçatandır.
  • Açıq ötürmə olmadan — ara View-lər obyekt haqqında bilmək məcburiyyətində deyil, bu arxitekturanı sadələşdirir.
  • Runtime crash — obyekt mühitdə tapılmazsa, tətbiq fatal error ilə çökür.
  • iOS 13+ — @EnvironmentObject SwiftUI-nin ilk versiyasından mövcuddur.

SwiftUI-də @EnvironmentObject nədir

@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.

swift
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 necə işləyir

@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.

Mühitdə obyektin axtarışı

  • Cari View-dən yuxarı — SwiftUI cari View-in mühitini, sonra valideynin mühitini və s. kökə qədər yoxlayır.
  • İlk tapılan obyekt — iyerarxiyada qalxarkən tapılan uyğun tipli ilk obyekt istifadə olunur.
  • Fatal error — obyekt heç bir səviyyədə tapılmazsa, tətbiq "ObservableObject tapılmadı" xətası ilə çökür.

@EnvironmentObject vs @ObservedObject: müqayisə

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ürAşkar — View init-də görünür
Ara View-lərObyekt haqqında bilmirObyekti irəli ötürməlidir
Xəta riskiObyekt olmadıqda runtime crashKompilyasiya vaxtı yoxlaması (parametr məcburidirsə)
Prop drillingAradan 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.

@EnvironmentObject istifadə nümunələri

Ə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.

swift
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.

Tipik səhvlər və risklər

@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.

Crash-dan necə qorunmaq olar

  • Qlobal inject — obyekti ən yüksək səviyyədə (WindowGroup) inject edin ki, bütün ekranlar üçün əlçatan olsun.
  • Preview-də yoxlama — SwiftUI Preview-də həmişə .environmentObject() əlavə edin, əks halda Preview çökəcək.
  • Sənədləşdirmə və testlər — View-in hansı @EnvironmentObject gözlədiyini sənədləşdirin və onların mövcudluğunu yoxlayan testlər yazın.
  • @ObservedObject ilə əvəz — obyekt yalnız bir ekrana lazımdırsa, açıq ötürmə ilə @ObservedObject istifadə edin.

Çoxlu instansiyalar problemi

İ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ə.

@EnvironmentObject alternativləri

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.

  • @Environment property wrapper — daxili mühit dəyərləri üçün (colorScheme, locale, sizeCategory). Xüsusi ObservableObject üçün uyğun deyil, yalnız standart EnvironmentValues açarları üçün.
  • Custom EnvironmentKey — dəyər tipləri üçün xüsusi mühit açarı elan etmək olar. ObservableObject-i reference semantics səbəbindən EnvironmentValues-da saxlamaq tövsiyə edilmir.
  • Açıq ötürmə ilə @ObservedObject — kompilyasiya vaxtı yoxlaması ilə təhlükəsiz yanaşma. View tələb olunan obyekt olmadan görünə bilməz — init vasitəsilə ötürülməlidir.
  • Dependency Injection konteyneri — SwiftUI-dən kənar asılılıqları idarə etmək üçün xarici DI konteyneri (məsələn, Resolver və ya Swinject).

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

Bir View-də bir neçə @EnvironmentObject istifadə etmək olar?

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.

.environmentObject() olmadan Preview vasitəsilə @EnvironmentObject inject etsəniz nə olar?

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.

@EnvironmentObject protokollarla istifadə edilə bilər?

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.

@EnvironmentObject istifadə edən View-i necə test etmək olar?

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.

Çox sayda ekran olduqda @EnvironmentObject performansa təsir edirmi?

@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ə

  • @EnvironmentObject — SwiftUI mühitindən ObservableObject-ə initiator vasitəsilə açıq ötürmə olmadan giriş üçün property wrapper.
  • .environmentObject() vasitəsilə inject — obyekt iyerarxiyanın müəyyən səviyyəsində mühitə yerləşdirilir.
  • Avtomatik axtarış — SwiftUI tipdən açar kimi istifadə edərək iyerarxiyada yuxarıya doğru obyekti axtarır.
  • Runtime crash — obyekt tapılmazsa, tətbiq fatal error ilə çökür, bu ehtiyatlılıq tələb edir.
  • Prop drilling həlli — @EnvironmentObject məlumatları ara View-lər vasitəsilə ötürmək zərurətini aradan qaldırır.
  • Gizli asılılıqlar — asılılıqlar View imzasında görünmür, bu kodu başa düşməyi çətinləşdirir.
  • Alternativlər — açıq ötürmə üçün @ObservedObject, böyük layihələr üçün DI konteynerləri.

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.

Layihəni müzakirə et

Həm də oxuyun