@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 میں سے ایک ہے، اور یہ @Observable میکرو سمیت iOS 17 اور 18 سمیت تمام بعد کے ورژنز میں کام کرتا ہے۔
آبجیکٹ کی تعداد لا محدود ہے — ہر قسم منفرد کلید کے طور پر کام کرتی ہے۔ AuthManager، CartManager، NavigationManager اور دیگر خدمات کو ہر ایک کے لیے علیحدہ علیحدہ .environmentObject() کال کر کے منتقل کیا جا سکتا ہے۔ یہ ضروری ہے کہ ماحول میں ایک ہی قسم کے دو آبجیکٹ نہ ہوں — یہ غیر متعینہ رویے کا سبب بنے گا۔
ٹیسٹ میں، ObservableObject کی ایک مثال بنائیں اور اسے Preview Provider یا XCTest میں .environmentObject(obj) کے ذریعے منتقل کریں۔ ویو انجیکشن کے یونٹ ٹیسٹ کے لیے، ٹھوس کلاس کے بجائے پروٹوکول استعمال کرنا آسان ہے — یہ حقیقی درجہ بندی کو تبدیل کیے بغیر انحصار کو موک آبجیکٹ سے تبدیل کرنے کی اجازت دیتا ہے۔
خلاصہ
.environmentObject() کے ذریعے ماحول میں رکھا جاتا ہے اور قسم کے مطابق نکالا جاتا ہےہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں