@EnvironmentObject SwiftUI में एक property wrapper है जो संपूर्ण व्यू पदानुक्रम के माध्यम से ObservableObject को इनिशियलाइज़र में स्पष्ट पासिंग के बिना स्वचालित रूप से पास करता है। चाइल्ड व्यू केवल एक प्रॉपर्टी घोषित करके एनवायरनमेंट ऑब्जेक्ट तक पहुँच प्राप्त करता है, जबकि पैरेंट इसे .environmentObject() विधि के माध्यम से प्रदान करता है। Apple Developer Documentation (2025) के अनुसार, SwiftUI पर्यावरण स्तर पर डिपेंडेंसी इंजेक्शन तंत्र का उपयोग करता है, जो मध्यवर्ती व्यू के कंस्ट्रक्टर के माध्यम से डेटा पास करने की आवश्यकता को समाप्त करता है। @EnvironmentObject उन ऑब्जेक्ट के लिए विशेष रूप से उपयोगी है जिनकी एप्लिकेशन की कई स्क्रीन को आवश्यकता होती है — प्रमाणीकरण मॉडल, शॉपिंग कार्ट या वैश्विक सेटिंग्स।
मुख्य बिंदु
.environmentObject() विधि द्वारा किया जाता है — ऑब्जेक्ट सभी चाइल्ड एलिमेंट के लिए उपलब्ध हो जाता है@Environment के माध्यम से काम करना जारी रखता है@EnvironmentObject SwiftUI फ्रेमवर्क में घोषित एक property wrapper है जो व्यू को पर्यावरण में संग्रहीत ऑब्जेक्ट तक पहुँचने की अनुमति देता है। @State या @StateObject के विपरीत, @EnvironmentObject कोई ऑब्जेक्ट नहीं बनाता — यह केवल व्यू पदानुक्रम में पूर्वजों में से किसी एक द्वारा प्रदान की गई मौजूदा इंस्टेंस को पढ़ता है।
तंत्र SwiftUI पर्यावरण पर आधारित है — एक अंतर्निहित शब्दकोश जो रूट व्यू से सभी चाइल्ड व्यू तक पास होता है। जब पैरेंट .environmentObject(someObject) विधि को कॉल करता है, SwiftUI पर्यावरण में someObject का संदर्भ रखता है। उपट्री में कोई भी व्यू @EnvironmentObject var model: ViewModel घोषित कर सकता है और वही इंस्टेंस प्राप्त कर सकता है।
Apple WWDC 2021 सत्र “Demystify SwiftUI” के अनुसार, पर्यावरण प्रदर्शन हानि के बिना गहरे पदानुक्रम के माध्यम से डेटा पास करने के लिए अनुकूलित है — ऑब्जेक्ट तक पहुँच प्रकार-आधारित लुकअप के माध्यम से O(1) में होती है। यह कंस्ट्रक्टर के माध्यम से मैन्युअल पासिंग के विपरीत है, जहाँ जटिलता पदानुक्रम की गहराई के साथ रैखिक रूप से बढ़ती है।
एप्लिकेशन के विभिन्न स्तरों पर आवश्यक वैश्विक स्थिति के लिए @EnvironmentObject का उपयोग करें। विशिष्ट उम्मीदवार प्रमाणीकरण मॉडल, नेविगेशन मैनेजर, शॉपिंग कार्ट और नेटवर्क डेटा प्रदाता हैं।
@EnvironmentObject पर्यावरण-आधारित डिपेंडेंसी इंजेक्शन नामक SwiftUI तंत्र का उपयोग करता है। जब SwiftUI पदानुक्रम को रेंडर करता है, यह एक आंतरिक शब्दकोश EnvironmentValues बनाए रखता है, जो प्रत्येक स्तर पर पढ़ने और लिखने के लिए सुलभ होता है। @EnvironmentObject property wrapper इस शब्दकोश से प्रकार के अनुसार पढ़ता है, परिवर्तनों की सदस्यता लेने के लिए ObservableObject प्रोटोकॉल से objectWillChange का उपयोग करता है।
प्रक्रिया तीन चरणों में होती है। पहला, पदानुक्रम में कहीं ObservableObject बनाना, आमतौर पर पैरेंट व्यू पर @StateObject या @ObservedObject के माध्यम से। दूसरा, उस व्यू पर .environmentObject(object) कॉल करना, जो ऑब्जेक्ट को पर्यावरण में रखता है। तीसरा, चाइल्ड व्यू में @EnvironmentObject घोषित करना, जो स्वचालित रूप से उसी इंस्टेंस को प्राप्त और सब्सक्राइब करते हैं।
SwiftUI गारंटी देता है कि जब भी ऑब्जेक्ट के अंदर कोई @Published प्रॉपर्टी बदलती है, इस प्रकार के साथ @EnvironmentObject घोषित करने वाले सभी व्यू पुनः रेंडर होंगे। Donny Wals (2024) के एक लेख के अनुसार, सब्सक्रिप्शन तंत्र @ObservedObject के समान है — अंतर केवल इंस्टेंस प्राप्त करने के तरीके में है, अपडेट तंत्र में नहीं।
पदानुक्रम को इस प्रकार डिज़ाइन करें कि ऑब्जेक्ट यथासंभव ऊपर प्रदान किया जाए — यह कोड दोहराव के बिना सभी आवश्यक व्यू के लिए पहुँच सुनिश्चित करता है।
दोनों property wrappers — @EnvironmentObject और @ObservedObject — ObservableObject की सदस्यता लेते हैं और परिवर्तनों पर व्यू को पुनः रेंडर करते हैं। मुख्य अंतर ऑब्जेक्ट प्राप्त करने के तरीके में है। @ObservedObject को व्यू इनिशियलाइज़र के माध्यम से इंस्टेंस के स्पष्ट पासिंग की आवश्यकता होती है, जबकि @EnvironmentObject इसे पर्यावरण से स्वचालित रूप से प्राप्त करता है।
तीन स्तरों के पदानुक्रम पर विचार करें: ParentView → MiddleView → ChildView. यदि ChildView को UserSettings ऑब्जेक्ट की आवश्यकता है, @ObservedObject का उपयोग करने पर इसे MiddleView के माध्यम से पास करना होगा, भले ही MiddleView इस ऑब्जेक्ट का उपयोग न करता हो:
struct MiddleView: View {
@ObservedObject var settings: UserSettings // only needed to pass down
var body: some View {
ChildView(settings: settings)
}
}
@EnvironmentObject के साथ, MiddleView को ऑब्जेक्ट के अस्तित्व के बारे में जानने की आवश्यकता नहीं है:
struct MiddleView: View {
var body: some View {
ChildView()
}
}
struct ChildView: View {
@EnvironmentObject var settings: UserSettings
var body: some View {
Text(settings.username)
}
}
Swift by Sundell (2024) के अनुसार, @EnvironmentObject तब पसंद किया जाता है जब ऑब्जेक्ट पदानुक्रम के कई स्तरों पर आवश्यक हो, जबकि @ObservedObject तब बेहतर होता है जब ऑब्जेक्ट सीधे पैरेंट से एकमात्र प्रत्यक्ष चाइल्ड को पास किया जाता है। स्थानीय, एकल पास के लिए @ObservedObject चुनें और वैश्विक निर्भरताओं के लिए @EnvironmentObject चुनें।
@Environment और @EnvironmentObject दोनों SwiftUI पर्यावरण से डेटा पढ़ते हैं, लेकिन विभिन्न स्रोतों के साथ काम करते हैं। @Environment EnvironmentValues से अंतर्निहित या कस्टम मान पढ़ता है — ये सरल डेटा हैं: रंग, फ़ॉन्ट, आकार, कैलेंडर, layoutDirection। @EnvironmentObject ObservableObject के अनुरूप संदर्भ प्रकार पढ़ता है।
मुख्य अंतर अपडेट तंत्र है। @Environment व्यक्तिगत मान स्तर पर publish-subscribe का उपयोग करता है: जब पर्यावरण बदलता है, केवल वे व्यू पुनः रेंडर होते हैं जो उस मान को पढ़ रहे हैं। @EnvironmentObject ObservableObject के objectWillChange की सदस्यता लेता है, जो इस प्रकार की सदस्यता लेने वाले सभी व्यू को पुनः रेंडर कर सकता है, भले ही कौन सी विशिष्ट प्रॉपर्टी बदली हो।
Hacking with Swift (Paul Hudson, 2025) के अनुसार, @Environment कॉन्फ़िगरेशन पैरामीटर के लिए उपयुक्त है: रंग योजना, गतिशील फ़ॉन्ट आकार, डिवाइस ओरिएंटेशन। @EnvironmentObject व्यावसायिक तर्क और स्थिति के लिए है: डेटा मॉडल, सेवाएँ, मैनेजर। स्थिर या शायद ही बदलने वाले पैरामीटर के लिए @Environment का उपयोग करें और प्रतिक्रियाशीलता की आवश्यकता वाले गतिशील डेटा के लिए @EnvironmentObject का उपयोग करें।
व्यवहार में, ये दो तंत्र अक्सर संयुक्त होते हैं: @EnvironmentObject डेटा प्रदान करता है, जबकि @Environment प्रदर्शन संदर्भ प्रदान करता है।
सबसे सामान्य गलती है उस तक पहुँचने पर पर्यावरण में ऑब्जेक्ट की अनुपस्थिति. यदि कोई व्यू @EnvironmentObject var model: ViewModel घोषित करता है, लेकिन किसी पूर्वज ने .environmentObject(model) कॉल नहीं किया, SwiftUI संदेश के साथ fatal error फेंकेगा: “ViewModel प्रकार का ObservableObject नहीं मिला.” यह रेंडर समय पर होता है, संकलन समय पर नहीं, इसलिए त्रुटि केवल रनटाइम पर दिखाई दे सकती है।
दूसरी सामान्य समस्या है एक ही प्रकार के एकाधिक इंस्टेंस. SwiftUI पर्यावरण में लुकअप के लिए कुंजी के रूप में ऑब्जेक्ट प्रकार का उपयोग करता है। यदि दो अलग-अलग पूर्वजों ने .environmentObject के माध्यम से ViewModel के अलग-अलग इंस्टेंस प्रदान किए, चाइल्ड व्यू पदानुक्रम में निकटतम प्राप्त करेगा, जो अप्रत्याशित व्यवहार का कारण बन सकता है। समाधान यह डिज़ाइन करना है कि प्रत्येक प्रकार पर्यावरण में ठीक एक बार दिखाई दे।
तीसरी गलती है उन डेटा के लिए @EnvironmentObject का अत्यधिक उपयोग जिनकी केवल एक या दो व्यू को आवश्यकता है। इस मामले में, इनिशियलाइज़र के माध्यम से स्पष्ट पासिंग वाला @ObservedObject अधिक पारदर्शी डेटा प्रवाह प्रदान करता है और परीक्षण को सरल बनाता है। Point-Free (2025) के अनुसार, पर्यावरण में ऑब्जेक्ट की अत्यधिक संख्या व्यू निर्भरताओं को समझना कठिन बना देती है और कोड को कम पूर्वानुमानित बना देती है।
जाँचें कि प्रत्येक @EnvironmentObject पदानुक्रम के सही स्तर पर प्रदान किया गया है, और अनुपस्थिति को जल्दी पकड़ने के लिए महत्वपूर्ण ऑब्जेक्ट के लिए onAppear में फ़ॉलबैक जाँच जोड़ें।
वैश्विक प्रमाणीकरण स्थिति वाले एप्लिकेशन का पूर्ण उदाहरण लें। हम एक ObservableObject AuthManager बनाएंगे जो उपयोगकर्ता लॉगिन स्थिति संग्रहीत करता है, और इसे @EnvironmentObject के माध्यम से सभी स्क्रीन को प्रदान करेंगे:
import SwiftUI
import Combine
class AuthManager: ObservableObject {
@Published var isLoggedIn = false
@Published var username: String = ""
func login(user: String) {
username = user
isLoggedIn = true
}
func logout() {
username = ""
isLoggedIn = false
}
}
रूट व्यू पर्यावरण के माध्यम से AuthManager प्रदान करता है:
@main
struct MyApp: App {
@StateObject private var authManager = AuthManager()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(authManager)
}
}
}
चाइल्ड व्यू स्पष्ट पासिंग के बिना AuthManager प्राप्त करता है:
struct ProfileView: View {
@EnvironmentObject var authManager: AuthManager
var body: some View {
VStack {
if authManager.isLoggedIn {
Text("Hello, \(authManager.username)")
Button("Log Out") {
authManager.logout()
}
} else {
Button("Log In") {
authManager.login(user: "user")
}
}
}
}
}
तीसरा उदाहरण एकाधिक ObservableObjects और @EnvironmentObject के साथ @Environment के संयोजन से संबंधित है। मान लें कि एप्लिकेशन शॉपिंग कार्ट के लिए CartManager और रंग योजना के लिए ThemeManager का उपयोग करता है। दोनों शीर्ष स्तर पर प्रदान किए जाते हैं और इनिशियलाइज़र के माध्यम से पास किए बिना किसी भी स्क्रीन पर उपलब्ध होते हैं। यह विशेष रूप से गहराई से नेस्टेड स्क्रीन या मोडल प्रस्तुतियों के साथ सुविधाजनक है, जहाँ कंस्ट्रक्टर के माध्यम से डेटा पास करना तकनीकी रूप से कठिन है।
अक्सर पूछे जाने वाले प्रश्न
@ObservedObject को व्यू इनिशियलाइज़र के माध्यम से इंस्टेंस के स्पष्ट पासिंग की आवश्यकता होती है, जबकि @EnvironmentObject ऑब्जेक्ट को SwiftUI पर्यावरण से स्वचालित रूप से प्राप्त करता है। @EnvironmentObject पदानुक्रम के कई स्तरों पर आवश्यक डेटा के लिए सुविधाजनक है, जबकि @ObservedObject पैरेंट और चाइल्ड के बीच सीधे पासिंग के लिए पसंद किया जाता है।
SwiftUI रनटाइम पर fatal error फेंकेगा: “X प्रकार का ObservableObject नहीं मिला.” त्रुटि उस व्यू को रेंडर करने के समय होती है जिसने @EnvironmentObject घोषित किया, यदि किसी पूर्वज ने इस प्रकार के ऑब्जेक्ट के साथ .environmentObject() कॉल नहीं किया। कंपाइलर इस स्थिति के बारे में चेतावनी नहीं देगा।
हाँ, @EnvironmentObject iOS 13.0, macOS 10.15, tvOS 13.0 और watchOS 6.0 से उपलब्ध है। यह Apple द्वारा 2019 में SwiftUI के साथ प्रस्तुत पहले property wrappers में से एक है, और यह iOS 17 और 18 सहित @Observable मैक्रो के साथ सभी बाद के संस्करणों में काम करता है।
ऑब्जेक्ट की संख्या असीमित है — प्रत्येक प्रकार अद्वितीय कुंजी के रूप में कार्य करता है। AuthManager, CartManager, NavigationManager और अन्य सेवाओं को प्रत्येक के लिए अलग-अलग .environmentObject() कॉल करके पास किया जा सकता है। यह महत्वपूर्ण है कि पर्यावरण में एक ही प्रकार के दो ऑब्जेक्ट न हों — यह अपरिभाषित व्यवहार का कारण बनेगा।
परीक्षणों में, ObservableObject की एक इंस्टेंस बनाएँ और इसे Preview Provider या XCTest में .environmentObject(obj) के माध्यम से पास करें। व्यू इंजेक्शन के यूनिट परीक्षण के लिए, ठोस वर्ग के बजाय प्रोटोकॉल का उपयोग करना सुविधाजनक है — यह वास्तविक पदानुक्रम को बदले बिना निर्भरताओं को मॉक ऑब्जेक्ट से बदलने की अनुमति देता है।
सारांश
.environmentObject() के माध्यम से पर्यावरण में रखा जाता है और प्रकार के अनुसार निकाला जाता हैहम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें