Combine হল Apple-এর একটি রিঅ্যাকটিভ প্রোগ্রামিং ফ্রেমওয়ার্ক, যা iOS 13-এ প্রবর্তিত হয়েছে। Apple Documentation, 2025 অনুযায়ী, Combine অ্যাসিঙ্ক্রোনাস ইভেন্টগুলি পরিচালনার জন্য একটি ইউনিফায়েড ডিক্লারেটিভ API প্রদান করে। Publisher ডেটা উৎস নির্ধারণ করে, এবং Subscriber সেগুলি পাওয়ার জন্য সাবস্ক্রাইব করে।
মূল বিষয়
Combine হল সময়ের সাথে অ্যাসিঙ্ক্রোনাস ইভেন্ট প্রক্রিয়াকরণের জন্য একটি ডিক্লারেটিভ Swift ফ্রেমওয়ার্ক। কলব্যাক-ভিত্তিক পদ্ধতির বিপরীতে, Combine অপারেটরগুলির একটি চেইনের মাধ্যমে ডেটা প্রসেসিং পাইপলাইন বর্ণনা করার অনুমতি দেয়। ফ্রেমওয়ার্কটি Foundation (URLSession, Timer, NotificationCenter) এবং SwiftUI (ObservableObject, @Published) এর সাথে একীভূত।
যেকোনো টাইপ যা Publisher প্রোটোকল প্রয়োগ করে, তাকে Output (মানের টাইপ) এবং Failure (ত্রুটির টাইপ) নির্ধারণ করতে হবে। Publisher সাবস্ক্রাইব না হওয়া পর্যন্ত সক্রিয় হয় না — এটি subscribe কল করার পরেই ইভেন্ট নির্গত করা শুরু করে। এটি কোল্ড সিম্যান্টিক্স, রিঅ্যাকটিভ স্ট্রিমের বৈশিষ্ট্য, যা দক্ষতা উন্নত করে।
Subscriber তিনটি পদ্ধতির মাধ্যমে ইভেন্ট গ্রহণ করে: receive(subscription:) — ডিমান্ড ম্যানেজমেন্ট সহ সাবস্ক্রিপশন নিশ্চিতকরণ; receive(_:) — একটি নতুন মান গ্রহণ; receive(completion:) — সাফল্য বা ত্রুটির সাথে স্ট্রিম সমাপ্তি। Demand নির্দিষ্ট করে Subscriber কতগুলি মান গ্রহণ করতে প্রস্তুত — এটি ব্যাকপ্রেশার প্রক্রিয়া।
Apple অনেক বিল্ট-ইন Publisher প্রদান করে: Just একটি মান নির্গত করে এবং সমাপ্ত হয়, Future — একটি ক্লোজার সহ অ্যাসিঙ্ক্রোনাস ফলাফল, Deferred — সাবস্ক্রিপশনের মুহূর্ত পর্যন্ত Publisher-এর বিলম্বিত সৃষ্টি। URLSession.dataTaskPublisher নেটওয়ার্ক অনুরোধকে রিঅ্যাকটিভ স্ট্রিমে রূপান্তর করে। Timer.publish একটি পর্যায়ক্রমিক টাইমার তৈরি করে। NotificationCenter.default.publisher বিজ্ঞপ্তিগুলিকে Publisher-এ রূপান্তর করে। এই ইন্টিগ্রেশনগুলি ম্যানুয়াল ব্রিজিং ছাড়াই ইভেন্টে সাবস্ক্রাইব করার অনুমতি দেয়।
Combine-এ, Publisher এবং Subscriber Subscription প্রোটোকলের মাধ্যমে সংযুক্ত। Subscription是一个 সংযোগকারী অবজেক্ট যা ডেটা প্রবাহ নিয়ন্ত্রণ করে। ডেভেলপারদের নিজস্ব Publisher টাইপ তৈরি করার প্রয়োজন নেই — Apple বিল্ট-ইন টাইপ প্রদান করে: Just, Future, Deferred, Fail, Empty, পাশাপাশি URLSession এবং Timer-এর জন্য Publisher।
Subject হল একটি Publisher যাতে ম্যানুয়ালি মান পাঠানো যায়। PassthroughSubject অবস্থা সংরক্ষণ করে না: একজন সাবস্ক্রাইবার শুধুমাত্র সেই ইভেন্টগুলি পায় যা সাবস্ক্রিপশনের পরে ঘটেছে। CurrentValueSubject, RxSwift-এর BehaviorRelay-এর অনুরূপ, বর্তমান মান সংরক্ষণ করে এবং তা অবিলম্বে নতুন সাবস্ক্রাইবারদের কাছে প্রেরণ করে।
Combine-এ ব্যাকপ্রেশার প্রক্রিয়া ডেটা স্থানান্তর গতি নিয়ন্ত্রণ করে। Subscriber subscription.request(.unlimited) বা subscription.request(.max(N)) এর মাধ্যমে Publisher-কে জানায় সে কতগুলি মান প্রক্রিয়া করতে প্রস্তুত। এটি প্রযোজক এবং ভোক্তার গতি অসম হলে বাফার ওভারফ্লো প্রতিরোধ করে।
Combine-এ 100টিরও বেশি অপারেটর রয়েছে, যা বিভাগে বিভক্ত: রূপান্তর (map, tryMap, flatMap), ফিল্টারিং (filter, compactMap, removeDuplicates), সংযোজন (combineLatest, merge, zip), সময় ব্যবস্থাপনা (debounce, throttle, delay), এবং ত্রুটি ব্যবস্থাপনা (catch, replaceError, retry)।
combineLatest অপারেটর দুটি Publisher-এর সর্বশেষ মানগুলিকে সংযুক্ত করে — প্রতিবার যখন কোনও একটি নতুন মান নির্গত করে, ক্লোজারটি উভয় আপডেট করা মান সহ কল করা হয়। এই অপারেটর ফর্ম বৈধতার জন্য অপরিহার্য যেখানে একসাথে একাধিক ইনপুট ফিল্ডের অবস্থা ট্র্যাক করতে হয়।
debounce অপারেটর নতুন ইভেন্ট ছাড়া নির্দিষ্ট ব্যবধান অতিক্রম না হওয়া পর্যন্ত মান প্রকাশে বিলম্ব করে। এটি অনুসন্ধান ক্ষেত্রগুলির জন্য গুরুত্বপূর্ণ: সার্ভার অনুরোধ তখনই পাঠানো হয় যখন ব্যবহারকারী 300–500 ms ধরে টাইপ করা বন্ধ করে দেয়, যা লোড 5–10 গুণ কমিয়ে দেয়।
Combine অপারেটর স্তরে ত্রুটি ব্যবস্থাপনার বেশ কয়েকটি কৌশল প্রদান করে। catch Failure আটকায় এবং Publisher-কে একটি ফলব্যাক দিয়ে প্রতিস্থাপন করে — স্ট্রিম ক্র্যাশ ছাড়াই চলতে থাকে। replaceError(with:) ত্রুটির পরিবর্তে একটি ডিফল্ট মান প্রদান করে। retry(_:) ব্যর্থতায় নির্দিষ্ট সংখ্যক বার সাবস্ক্রিপশন পুনরায় চেষ্টা করে। গুরুত্বপূর্ণ: Publisher স্বাক্ষরে Never ত্রুটি টাইপ গ্যারান্টি দেয় যে স্ট্রিম কখনও ত্রুটির সাথে সমাপ্ত হবে না — এটি SwiftUI-এ Failure ব্যবস্থাপনা ছাড়াই Publisher ব্যবহারের অনুমতি দেয়।
প্রথম উদাহরণ Just-এর মৌলিক ব্যবহার দেখায় — একটি Publisher যা একটি মান নির্গত করে এবং সমাপ্ত হয়:
let publisher = Just("Hello Combine")
publisher
.sink(receiveCompletion: { completion in
print("সমাপ্ত: \(completion)")
}, receiveValue: { value in
print("প্রাপ্ত: \(value)")
})
দ্বিতীয় উদাহরণ মূল থ্রেডে ফলাফল প্রক্রিয়াকরণ সহ নেটওয়ার্ক অনুরোধের জন্য Combine-এর URLSession-এর সাথে একীকরণ প্রদর্শন করে:
let url = URL(string: "https://api.example.com")!
URLSession.shared
.dataTaskPublisher(for: url)
.map { $0.data }
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { completion in
if case .failure(let error) = completion {
print("ত্রুটি: \(error)")
}
}, receiveValue: { data in
print("প্রাপ্ত ডেটা: \(data.count)")
})
তৃতীয় উদাহরণ অবস্থা ব্যবস্থাপনার জন্য CurrentValueSubject-এর ব্যবহার দেখায়:
let counter = CurrentValueSubject<Int, Never>(0)
counter
.sink { value in
print("কাউন্টার: \(value)")
}
counter.send(1) // প্রিন্ট করে: কাউন্টার: 1
counter.send(2) // প্রিন্ট করে: কাউন্টার: 2
print(counter.value) // প্রিন্ট করে: 2
Combine এবং RxSwift একই সমস্যা — রিঅ্যাকটিভ প্রোগ্রামিং — সমাধান করে, কিন্তু ভিন্ন পদ্ধতিতে। Combine একটি নেটিভ Apple ফ্রেমওয়ার্ক যা সিস্টেমে নির্মিত: কোনো নির্ভরতা ইনস্টলেশনের প্রয়োজন নেই, SwiftUI এবং Foundation-এর সাথে একীভূত। RxSwift iOS 9+ সমর্থন এবং অপারেটরগুলির বিস্তৃত সেট সহ একটি থার্ড-পার্টি লাইব্রেরি।
নেটিভ C বাস্তবায়নের কারণে সাধারণ পরিস্থিতিতে Combine-এর কর্মক্ষমতা বেশি। RxSwift আরও ডিবাগিং টুল (RxSwift.Resources.total, Debug) প্রদান করে, কিন্তু এর অবজেক্ট-ওরিয়েন্টেড আর্কিটেকচার বড় ডেটা স্ট্রিমে কম কার্যকর হতে পারে। তাদের মধ্যে নির্বাচন হল ক্ষমতা এবং একীকরণের মধ্যে একটি আপস।
একটি গুরুত্বপূর্ণ পার্থক্য হল ব্যাকপ্রেশার মডেল। Combine-এ, Subscriber Subscription-এর মাধ্যমে ডিমান্ড পরিচালনা করে, স্ট্রিম গতির উপর স্পষ্ট নিয়ন্ত্রণ দেয়। RxSwift-এ, ব্যাকপ্রেশার ডিফল্টভাবে নিয়ন্ত্রিত হয় না — Observable সমস্ত মান নির্গত করে, এবং Subscriber সেগুলি আসার সাথে সাথে প্রক্রিয়া করে। বড় ডেটা স্ট্রিমের জন্য, Combine বেশি পূর্বাভাসযোগ্য এবং মেমরি-নিরাপদ।
Combine ভাষা স্তরে SwiftUI-এর সাথে গভীরভাবে একীভূত। @Published একটি Publisher তৈরি করে, ObservableObject objectWillChange Publisher প্রদান করে। SwiftUI View স্বয়ংক্রিয়ভাবে এই Publisher-গুলিতে সাবস্ক্রাইব করে এবং পরিবর্তনে পুনরায় আঁকে। UIKit-এর জন্য CombineCocoa-এর মতো থার্ড-পার্টি র্যাপার রয়েছে, কিন্তু Combine মূলত SwiftUI-এর জন্য ডিজাইন করা হয়েছিল, তাই UIKit-এ এর একীকরণের জন্য অতিরিক্ত কোড প্রয়োজন। অন্যদিকে, RxSwift-এর UIKit-এর জন্য একটি সমৃদ্ধ ইকোসিস্টেম রয়েছে: RxCocoa সমস্ত UI উপাদানের জন্য রিঅ্যাকটিভ র্যাপার প্রদান করে।
Combine Core Data-এর সাথে NSFetchedResultsController Publisher-এর মাধ্যমে একীকরণ সমর্থন করে। Publisher Core Data স্ট্যাকের প্রতিটি পরিবর্তনে নতুন ডেটা নির্গত করে: রেকর্ড যোগ, মুছে ফেলা, আপডেট করা। এটি ম্যানুয়ালি reloadData কল না করেই রিঅ্যাকটিভ তালিকা তৈরি করার অনুমতি দেয়। Combine-কে UIApplication.willResignActiveNotification-এর জন্য NotificationCenter Publisher-এর সাথে সংযুক্ত করে, ডেভেলপাররা ডেলিগেট এবং কলব্যাক ছাড়াই সম্পূর্ণ অ্যাপ্লিকেশন জীবনচক্রের জন্য একটি রিঅ্যাকটিভ স্তর তৈরি করে। ObservableObject ক্লাসের জন্য, SwiftUI স্বয়ংক্রিয়ভাবে @Published বৈশিষ্ট্য পরিবর্তন হলে View আপডেট করে — Combine ম্যানুয়াল কোডের একটি লাইন ছাড়াই সম্পূর্ণ চেইন পরিচালনা করে। Combine কোডের ইউনিট টেস্টিং ImmediateScheduler-এর মাধ্যমে Scheduler বিচ্ছিন্নতা সহ টেস্ট কেসে XCTestExpectation এবং Publisher.sink-এর মাধ্যমে করা হয়।
UIKit প্রকল্পে Combine-এর সাথে কাজ করার সময়, ডেভেলপাররা প্রায়শই sink-এর মাধ্যমে সাবস্ক্রাইব করে এবং AnyCancellable একটি Set-এ সংরক্ষণ করে। সাধারণ প্যাটার্ন: ViewController একটি ভিউ তৈরি করে, cancellables সংরক্ষণ করে, ViewModel থেকে Publisher-এ সাবস্ক্রাইব করে। deinit-এ, Cancellables সংগ্রহের মাধ্যমে সমস্ত সাবস্ক্রিপশন স্বয়ংক্রিয়ভাবে বাতিল হয়ে যায়। Combine-এ UIControl-এর সঠিক পরিচালনার জন্য, publisher(for:) এক্সটেনশনের মাধ্যমে UIControl.Event Publisher ব্যবহার করা যেতে পারে।
Combine ডিবাগিং print() বা handleEvents() অপারেটরের মাধ্যমে করা হয়। print(String) সমস্ত ইভেন্ট লগ করে: receive subscription, request demand, receive value, receive completion। handleEvents আরও সূক্ষ্ম নিয়ন্ত্রণ প্রদান করে: Publisher জীবনচক্রের প্রতিটি ধাপের জন্য ক্লোজার নির্দিষ্ট করা যেতে পারে। পরীক্ষার জন্য, CombineExpectations — একটি লাইব্রেরি যা ভার্চুয়াল সময় এবং ডিমান্ড নিয়ন্ত্রণ সহ পরীক্ষায় Publisher প্রত্যাশিত মান নির্গত করে কিনা তা পরীক্ষা করার অনুমতি দেয়।
SwiftUI-তে ফর্ম পরিচালনার জন্য Combine সক্রিয়ভাবে ব্যবহৃত হয়: প্রতিটি @Published বৈশিষ্ট্য একটি Publisher তৈরি করে, SwiftUI View.body-এর মাধ্যমে এতে সাবস্ক্রাইব করে। combineLatest-এর মাধ্যমে একাধিক Publisher সংযুক্ত করে, ফর্ম বৈধতা ঘোষণামূলক হয়ে ওঠে: প্রতিটি Publisher একটি ফিল্ড ট্র্যাক করে, combineLatest সমস্ত মান সংগ্রহ করে, map সেগুলি বৈধতা দেয় এবং Submit বাটনের অবস্থা ফেরত দেয়। Publishers.Merge একই টাইপের একাধিক Publisher-কে একটিতে সংযুক্ত করে — বিভিন্ন নিয়ন্ত্রণ থেকে ইভেন্ট একটি একক স্ট্রিমে সংগ্রহ করার জন্য দরকারী।
UIKit-এর সাথে Combine একীকরণের জন্য, একটি এক্সটেনশনের মাধ্যমে UIControl Publisher ব্যবহার করুন: button.publisher(for: .touchUpInside) একটি Publisher ফেরত দেয় যা ট্যাপে ইভেন্ট নির্গত করে। CombineCocoa একটি কমিউনিটি লাইব্রেরি যা সমস্ত UIControl ইভেন্ট, UITextView.text, UIScrollView.contentOffset-এর জন্য Publisher প্রদান করে। সাবস্ক্রিপশন বাতিলে, cancellables Store deinit-এ পরিষ্কার হয়, গ্যারান্টি দেয় যে কোনও সাবস্ক্রিপশন তার মালিকের বেশি বাঁচবে না। একাধিক অবস্থা সহ UIControl-এর জন্য, Publisher-গুলিকে একটি অ্যারেতে সংযুক্ত করতে Publishers.MergeMany ব্যবহার করুন।
সচরাচর জিজ্ঞাসা
Combine iOS 13, macOS 10.15, tvOS 13 এবং watchOS 6 থেকে উপলব্ধ। এটি পুরোনো সংস্করণগুলির সমর্থন প্রয়োজন এমন প্রকল্পগুলিতে এর ব্যবহার সীমিত করে। iOS 12 এবং তার নিচের জন্য, RxSwift বা থার্ড-পার্টি লাইব্রেরি ব্যবহার করা হয়।
PassthroughSubject অবস্থা সংরক্ষণ করে না এবং নতুন সাবস্ক্রাইবারদের কাছে শেষ মান পুনরায় পাঠায় না — তারা কেবল ভবিষ্যতের ইভেন্ট পায়। CurrentValueSubject বর্তমান মান সংরক্ষণ করে এবং তা অবিলম্বে নতুন সাবস্ক্রাইবারদের কাছে প্রেরণ করে। CurrentValueSubject.value বর্তমান মান সিঙ্ক্রোনাসভাবে পড়া এবং লেখার অনুমতি দেয়।
Combine SwiftUI-এর মূল ভিত্তি: @Published একটি Publisher তৈরি করে, ObservableObject objectWillChange Publisher ব্যবহার করে। SwiftUI View Combine পাইপলাইনের মাধ্যমে @ObservedObject এবং @StateObject-এ স্বয়ংক্রিয়ভাবে সাবস্ক্রাইব করে, বৈশিষ্ট্য পরিবর্তন হলে View পুনরায় আঁকে।
ব্যাকপ্রেশার হল ডেটা স্থানান্তর গতি নিয়ন্ত্রণের একটি প্রক্রিয়া। Subscriber Subscription-কে জানায় সে কতগুলি মান প্রক্রিয়া করতে প্রস্তুত (demand)। Publisher অনুরোধের চেয়ে বেশি নির্গত করতে পারে না। নেটওয়ার্ক সকেট থেকে বড় ডেটা স্ট্রিমের সাথে কাজ করার সময় এটি গুরুত্বপূর্ণ।
catch অপারেটর ত্রুটি আটকায় এবং Publisher-কে একটি ফলব্যাক দিয়ে প্রতিস্থাপন করে। replaceError ত্রুটিকে একটি ডিফল্ট মান দিয়ে প্রতিস্থাপন করে। retry ত্রুটিতে নির্দিষ্ট সংখ্যক বার সাবস্ক্রিপশন পুনরায় চেষ্টা করে। Failure-এ ক্র্যাশ প্রতিরোধ করতে সমস্ত অপারেটর subscribe-এর আগে স্থাপন করা উচিত।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন