@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 এবং @Environment এর সাথে @EnvironmentObject-এর সংমিশ্রণ নিয়ে। ধরা যাক অ্যাপ্লিকেশন শপিং কার্টের জন্য 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন