.task { } — यह क्या है, async मॉडिफ़ायर और View में डेटा लोडिंग

लेखक: IT Sectr प्रकाशित: 2026-06-26 पढ़ने का समय: 9 मिनट

.task { } SwiftUI में iOS 15 में प्रस्तुत एक मॉडिफ़ायर है जो View के प्रकट होने पर एसिंक्रोनस ऑपरेशन शुरू करता है और View के गायब होने पर स्वचालित रूप से इसे रद्द कर देता है। .onAppear के विपरीत, जो बिना रद्दीकरण क्षमता के सिंक्रोनस कोड निष्पादित करता है, .task async/await कॉन्टेक्स्ट के साथ काम करता है और View के जीवनचक्र का ध्यान रखता है: जब View गायब होता है, SwiftUI बनाए गए Task पर cancel() कॉल करता है। यह मेमोरी लीक को रोकता है और View के अपडेट की आवश्यकता न होने के बाद भी ऑपरेशन को निष्पादित होने से रोकता है। Apple WWDC Session 10132 — Meet async/await in SwiftUI (2024) के अनुसार, .task SwiftUI में डेटा लोड करने का पसंदीदा तरीका है क्योंकि यह Structured Concurrency के साथ सुरक्षित रूप से काम करता है और एसिंक्रोनस ऑपरेशन के जीवनकाल को स्वचालित रूप से प्रबंधित करता है।

मुख्य बिंदु

  • .task { } — SwiftUI मॉडिफ़ायर जो View प्रकट होने पर एसिंक्रोनस डेटा लोड करता है, iOS 15 से उपलब्ध।
  • स्वचालित रद्दीकरण — View गायब होने पर SwiftUI Task को रद्द करता है, मेमोरी लीक रोकता है।
  • async/await कॉन्टेक्स्ट — .task के अंदर DispatchQueue या Combine की आवश्यकता के बिना async कॉल उपलब्ध हैं।
  • .task(id:) — पहचानकर्ता वाला वेरिएंट जो निर्दिष्ट मान बदलने पर कार्य पुनः शुरू करता है।
  • Structured Concurrency — .task समानांतर ऑपरेशन के लिए Structured Concurrency और TaskGroup का समर्थन करता है।

SwiftUI में .task { } क्या है

.task { } एक View मॉडिफ़ायर है जो View के स्क्रीन पर प्रकट होने पर async कॉन्टेक्स्ट में Task बनाता है। SwiftUI प्रदान किए गए क्लोज़र को बैकग्राउंड थ्रेड पर निष्पादित करता है, मुख्य थ्रेड को UI ऑपरेशन के लिए मुक्त रखता है। जब View गायब होता है, SwiftUI Structured Concurrency तंत्र के माध्यम से स्वचालित रूप से Task को रद्द कर देता है — यह सुनिश्चित करता है कि एसिंक्रोनस ऑपरेशन तब भी निष्पादित न हो जब उसका परिणाम आवश्यक न रह जाए।

Apple — Swift Programming Language (2025) के अनुसार, .task Swift 5.5 में प्रस्तुत Structured Concurrency की अवधारणा का उपयोग करता है। प्रत्येक .task पैरेंट View के कार्य के अंतर्गत एक चाइल्ड कार्य बनाता है। यदि पैरेंट कार्य रद्द हो जाता है (View गायब होता है), तो सभी चाइल्ड कार्य भी स्वचालित रूप से रद्द हो जाते हैं। यह DispatchWorkItem या AnyCancellable के संदर्भों को मैन्युअल रूप से संग्रहीत करने की तुलना में एसिंक्रोनस ऑपरेशन के जीवनचक्र प्रबंधन को मौलिक रूप से सरल बनाता है।

@State + .onAppear में मैन्युअल कॉल के पारंपरिक दृष्टिकोण के विपरीत, .task को बाद में रद्दीकरण के लिए Task का संदर्भ संग्रहीत करने की आवश्यकता नहीं होती। SwiftUI इसे स्वचालित रूप से करता है, बॉयलरप्लेट कोड को कम करता है और कार्य को रद्द करना भूल जाने के जोखिम को समाप्त करता है।

swift
struct ArticlesView: View {
    @State var articles: [Article] = []
    @State var error: Error?
    
    var body: some View {
        List(articles) { article in
            Text(article.title)
        }
        .task {
            do {
                articles = await APIClient().fetchArticles()
            } catch {
                self.error = error
            }
        }
    }
}

.task बनाम .onAppear: मुख्य अंतर

कई डेवलपर्स .onAppear में डेटा लोड करने के आदी हैं, लेकिन async/await और .task के आगमन के साथ, यह दृष्टिकोण पुराना हो गया है। .onAppear कोड को सिंक्रोनस रूप से निष्पादित करता है — .onAppear के अंदर एसिंक्रोनस ऑपरेशन के लिए, कॉल को Task { } में लपेटना और संभावित रद्दीकरण के लिए मैन्युअल रूप से उसका संदर्भ रखना आवश्यक है। .task यह स्वचालित रूप से करता है।

विशेषता.task { }.onAppear
Async कॉन्टेक्स्टअंतर्निहित async/awaitTask { } रैपर आवश्यक
स्वचालित रद्दीकरणहाँ, View गायब होने परनहीं, मैन्युअल रूप से लागू करना होगा
Structured Concurrencyसमर्थन करता हैसमर्थन नहीं करता
पुनः सक्रियणकेवल id बदलने परहर बार View प्रकट होने पर
Apple अनुशंसापसंदीदा तरीकासिंक्रोनस ऑपरेशन के लिए

.onAppear अभी भी सिंक्रोनस ऑपरेशन के लिए उपयोगी है — उदाहरण के लिए, लॉगिंग या प्रारंभिक UI सेटअप। लेकिन एसिंक्रोनस डेटा लोडिंग, नेटवर्क अनुरोध, डेटाबेस या फ़ाइल सिस्टम संचालन के लिए .task का उपयोग करें। यह आर्किटेक्चर की दृष्टि से सुरक्षित और स्वच्छ है।

swift
// ❌ पुराना तरीका: .onAppear में बिना रद्दीकरण के Task
var loadTask: Task<Void, Never>?
func body() { var body: some View { Text("") }
    .onAppear {
        loadTask = Task { await loadData() }
    }
    .onDisappear { loadTask?.cancel() }

// ✅ आधुनिक तरीका: .task रद्दीकरण प्रबंधित करता है
func body() { var body: some View { Text("") }
    .task { await loadData() }

.task(id:) — डेटा बदलने पर पुनः प्रारंभ

.task(id:) मॉडिफ़ायर एक अतिरिक्त पैरामीटर — पहचानकर्ता स्वीकार करता है। जब पहचानकर्ता का मान बदलता है, SwiftUI वर्तमान कार्य को रद्द करता है और नए पहचानकर्ता के साथ एक नया कार्य शुरू करता है। यह उन स्क्रीन के लिए आदर्श है जहाँ डेटा किसी चयनित पैरामीटर पर निर्भर करता है — उदाहरण के लिए, श्रेणी के अनुसार लेखों की सूची या ID के अनुसार उत्पाद विवरण।

swift
struct CategoryView: View {
    let categoryId: Int
    @State var items: [Item] = []
    
    var body: some View {
        List(items) { item in
            Text(item.name)
        }
        .task(id: categoryId) {
            await loadItems(for: categoryId)
        }
    }
    
    func loadItems(for id: Int) async {
        do {
            items = await APIClient().fetchItems(categoryId: id)
        } catch {
            // त्रुटि संभालें
        }
    }
}

जब categoryId बदलता है, SwiftUI पिछले अनुरोध को रद्द करता है और नया शुरू करता है। यह तेज़ श्रेणी स्विचिंग के दौरान विशेष रूप से महत्वपूर्ण है — पुराने अनुरोध राज्य अपडेट के लिए नए के साथ प्रतिस्पर्धा नहीं करेंगे। .task(id:) के बिना, आपको .onChange के माध्यम से मैन्युअल रूप से परिवर्तनों को ट्रैक करना और Task को मैन्युअल रूप से प्रबंधित करना होगा।

कार्य रद्दीकरण और isCancelled जाँच

हालाँकि .task View गायब होने पर कार्य को स्वचालित रूप से रद्द करता है, एसिंक्रोनस ऑपरेशन को स्वयं रद्दीकरण की सहकारी जाँच करनी चाहिए। Swift सहकारी रद्दीकरण मॉडल का उपयोग करता है — Task.cancel() निष्पादन को जबरन नहीं रोकता, बल्कि केवल isCancelled फ़्लैग सेट करता है। कार्य के अंदर कोड को समय-समय पर इस फ़्लैग की जाँच करनी चाहिए।

swift
struct LoadingView: View {
    @State var progress: Double = 0
    
    var body: some View {
        ProgressView(value: progress)
            .task {
                for i in 0..<100 {
                    // रद्दीकरण जाँचें
                    try Task.checkCancellation()
                    
                    await Task.sleep(nanoseconds: 50_000_000)
                    progress = Double(i + 1) / 100.0
                }
            }
    }
}

Task.checkCancellation() CancellationError फेंकता है यदि कार्य रद्द कर दिया गया हो। यह जाँच का सबसे सरल तरीका है — यह किसी भी async कॉन्टेक्स्ट में काम करता है। विकल्प महंगे ऑपरेशन से पहले Task.isCancelled को मैन्युअल रूप से जाँचना है। URLSession के लिए, नेटवर्क अनुरोध कार्य रद्द होने पर स्वचालित रूप से रद्द हो जाते हैं, क्योंकि URLSession मूल रूप से Structured Concurrency का समर्थन करता है।

.task के व्यावहारिक उदाहरण

.task कई परिदृश्यों के लिए उपयुक्त है: सरल JSON लोडिंग से TaskGroup के साथ जटिल समानांतर संचालन तक। आइए तीन विशिष्ट उपयोग मामलों को देखें।

त्रुटि प्रबंधन के साथ लोडिंग

swift
struct ProfileView: View {
    @State var profile: Profile?
    @State var isLoading = true
    
    var body: some View {
        Group {
            if isLoading {
                ProgressView()
            } else if let profile {
                Text(profile.name)
            } else {
                Text("लोड करने में विफल")
            }
        }
        .task {
            defer { isLoading = false }
            do {
                profile = await APIClient().fetchProfile()
            } catch {
                // प्रोफ़ाइल nil रहता है
            }
        }
    }
}

TaskGroup के साथ समानांतर लोडिंग

swift
struct DashboardView: View {
    @State var stats: DashboardStats?
    
    var body: some View {
        Text("डैशबोर्ड")
            .task {
                stats = await Task {
                    await withThrowingTaskGroup { group in
                        group.addTask { await API().fetchUsers() }
                        group.addTask { await API().fetchOrders() }
                        group.addTask { await API().fetchRevenue() }
                        
                        return DashboardStats(
                            users: try await group.next(),
                            orders: try await group.next(),
                            revenue: try await group.next()
                        )
                    }
                }.value
            }
    }
}

.task के साथ सामान्य गलतियाँ

सबसे आम गलती मुख्य थ्रेड पर स्विच किए बिना .task के अंदर UI गुणों को बदलना है। हालाँकि SwiftUI async कॉन्टेक्स्ट में @State को संशोधित करते समय स्वचालित रूप से अपडेट को मुख्य थ्रेड पर लौटाता है, .task के अंदर UIKit तत्वों का सीधा हेरफेर क्रैश का कारण बन सकता है।

  • try/catch भूल गए — .task त्रुटियों को स्वचालित रूप से नहीं संभालता। सभी थ्रोइंग फ़ंक्शन do/catch में लिपटे होने चाहिए, अन्यथा ऐप क्रैश हो जाएगा।
  • डेटा रेस — यदि कई .task(id:) अलग-अलग id के साथ शुरू किए जाते हैं और एक ही राज्य को अपडेट करते हैं, तो डेटा रेस हो सकती हैं। विभिन्न डेटा स्रोतों के लिए अलग-अलग गुणों का उपयोग करें।
  • लंबे सिंक्रोनस ऑपरेशन — .task सिंक्रोनस कोड को एसिंक्रोनस नहीं बनाता। यदि .task के अंदर भारी सिंक्रोनस काम है, तो इसे Task.detached में लपेटें या एक अलग async विधि में ले जाएँ।
  • CancellationError को अनदेखा करना — Task.checkCancellation() की जाँच करते समय, CancellationError को ऊपर प्रचारित किया जाना चाहिए, दबाया नहीं जाना चाहिए। रद्दीकरण को दबाने से मेमोरी लीक हो सकती है।
swift
// ❌ त्रुटि: कोई त्रुटि प्रबंधन नहीं
.task {
    let data = await fetchData() // त्रुटि होने पर क्रैश!
    items = data
}

// ✅ सही: do/catch
.task {
    do {
        items = await fetchData()
    } catch {
        errorMessage = error.localizedDescription
    }
}

अक्सर पूछे जाने वाले प्रश्न

.task और .onAppear में Task { } का उपयोग करने में क्या अंतर है?

.task स्वचालित रूप से View गायब होने पर कार्य रद्द करता है और Structured Concurrency का समर्थन करता है। .onAppear में Task { } को कार्य का संदर्भ मैन्युअल रूप से रखने और .onDisappear में cancel() कॉल करने की आवश्यकता होती है। .task पढ़ने में भी आसान है — यह स्पष्ट रूप से इंगित करता है कि डेटा लोडिंग View के जीवनचक्र का हिस्सा है।

क्या .task का उपयोग publisher की सदस्यता लेने के लिए किया जा सकता है?

हाँ, AsyncSequence या AsyncStream की सदस्यता लेने के लिए, .task के अंदर for await value in publisher.values का उपयोग करें। यह Publisher.values एक्सटेंशन के माध्यम से async/await और Combine दोनों के साथ काम करता है। जब View गायब होता है, पुनरावृत्ति स्वचालित रूप से समाप्त हो जाएगी और सदस्यता रद्द हो जाएगी।

.task TabView के साथ कैसे काम करता है — क्या टैब स्विच करने पर कार्य पुनः शुरू होता है?

हाँ, यदि TabView के अंदर View प्रत्येक स्विच पर पुनः बनाया जाता है। iOS 18 से, TabView Views को मेमोरी में रख सकता है — इस मामले में .task पुनः शुरू नहीं होता। यदि आपको प्रत्येक टैब स्विच पर डेटा पुनः लोड करने की आवश्यकता है, तो टैब पहचानकर्ता के साथ .task(id:) का उपयोग करें।

यदि .task वाला View अनुरोध पूरा होने से पहले गायब हो जाता है तो क्या होता है?

SwiftUI View गायब होने पर कार्य रद्द कर देगा। यदि URLSession अनुरोध कार्य के अंदर था, तो वह भी रद्द हो जाएगा। यदि कार्य सहकारी रद्दीकरण का समर्थन नहीं करता (उदाहरण के लिए, isCancelled की जाँच नहीं करता), तो यह निष्पादित होता रहेगा, लेकिन इसका परिणाम राज्य पर लागू नहीं होगा क्योंकि View अब मौजूद नहीं है।

क्या एक ही View पर कई .task मॉडिफ़ायर का उपयोग किया जा सकता है?

हाँ, आप एक ही View पर कई .task मॉडिफ़ायर जोड़ सकते हैं। प्रत्येक एक स्वतंत्र कार्य बनाता है। यह विभिन्न डेटा स्रोतों को अलग करने के लिए उपयोगी है: प्रोफ़ाइल लोड करने के लिए एक .task, WebSocket की सदस्यता लेने के लिए दूसरा, भू-स्थान की निगरानी के लिए तीसरा।

सारांश

  • .task { } — SwiftUI मॉडिफ़ायर View गायब होने पर स्वचालित रद्दीकरण के साथ एसिंक्रोनस ऑपरेशन के लिए।
  • async/await समर्थन — .task के अंदर Task रैपर की आवश्यकता के बिना पूर्ण async कॉन्टेक्स्ट उपलब्ध है।
  • .task(id:) — पहचानकर्ता बदलने पर कार्य पुनः शुरू करता है, मैन्युअल .onChange को बदलता है।
  • सहकारी रद्दीकरण — कार्य के अंदर रद्दीकरण जाँचने के लिए Task.checkCancellation() का उपयोग करें।
  • Structured Concurrency — .task चाइल्ड कार्यों के रद्दीकरण के साथ TaskGroup और समानांतर ऑपरेशन का समर्थन करता है।
  • .onAppear का विकल्प — एसिंक्रोनस डेटा लोडिंग के लिए, .onAppear + Task + .onDisappear पैटर्न के बजाय .task का उपयोग करें।
  • त्रुटि प्रबंधन — क्रैश रोकने के लिए .task के अंदर सभी async कॉल do/catch में लिपटी होनी चाहिए।

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें