कंबाइन फ्रेमवर्क में, एक प्रकाशक एक प्रकार है जो Publisher
प्रोटोकॉल के अनुरूप होता है। यह ग्राहकों को मूल्यों की धारा प्रदान करने के लिए ज़िम्मेदार है। Publisher
प्रोटोकॉल दो संबद्ध प्रकारों को परिभाषित करता है: Output
और Failure
, जो उन मानों के प्रकारों को इंगित करता है जो प्रकाशक उत्सर्जित कर सकता है और त्रुटियों के प्रकार जो वह फेंक सकता है, क्रमशः।
एक प्रकाशक समय के साथ एक या अधिक मान उत्सर्जित कर सकता है, और यह पूर्ण या विफल भी हो सकता है। जब कोई ग्राहक किसी प्रकाशक की सदस्यता लेता है, तो प्रकाशक ग्राहक की receive(subscription:)
विधि को कॉल करता है और इसे एक Subscription
ऑब्जेक्ट पास करता है, जिसका उपयोग ग्राहक मूल्यों के प्रवाह को नियंत्रित करने के लिए कर सकते हैं। सब्सक्राइबर नए मान प्राप्त करने के लिए प्रकाशक पर receive(_:)
विधि को भी कॉल कर सकता है।
कम्बाइन फ्रेमवर्क कई बिल्ट-इन पब्लिशर्स प्रदान करता है, जैसे कि Just
, Fail
, Empty
, Deferred
और Sequence
, जिनका उपयोग विभिन्न प्रकार के प्रकाशक बनाने के लिए किया जा सकता है। इसके अतिरिक्त, आप Publisher
प्रोटोकॉल के अनुरूप और आवश्यक विधियों को लागू करके अपने स्वयं के कस्टम प्रकाशक बना सकते हैं।
अधिक जटिल पाइपलाइन बनाने के लिए प्रकाशकों को भी एक साथ बनाया जा सकता है। कम्बाइन फ्रेमवर्क कई बिल्ट-इन ऑपरेटर्स प्रदान करता है जिनका उपयोग प्रकाशकों को संशोधित करने और संयोजित करने के लिए किया जा सकता है, जैसे map
, filter
, flatMap
reduce
zip
और merge
। ये ऑपरेटर Publisher
प्रोटोकॉल एक्सटेंशन द्वारा प्रदान किए जाते हैं और इन्हें किसी भी प्रकाशक पर कॉल किया जा सकता है।
अब मैं आपको कुछ उपयोगी प्रकाशकों की पेशकश करना चाहता हूं जिनका उपयोग मैं अपनी परियोजनाओं में करता हूं।
स्विफ्ट में एक कस्टम अंतराल के साथ दोहराए जाने वाले टाइमर का उपयोग करने वाले प्रकाशक को लागू करने के लिए, आप फाउंडेशन फ्रेमवर्क से Timer
क्लास का उपयोग कर सकते हैं। आप इसे कैसे कर सकते हैं इसका एक उदाहरण यहां दिया गया है:
RepeatingTimeSubscription
टाइम Subscription
प्रोटोकॉल के अनुरूप है:
private class RepeatingTimerSubscription<S: Subscriber>: Subscription where S.Input == Void { private let interval: TimeInterval private let queue: DispatchQueue private var subscriber: S? private var timer: Timer? init(interval: TimeInterval, queue: DispatchQueue, subscriber: S) { self.interval = interval self.queue = queue self.subscriber = subscriber } func request(_ demand: Subscribers.Demand) { timer?.invalidate() timer = Timer.scheduledTimer( withTimeInterval: interval, repeats: true ) { [weak self] _ in self?.queue.async { _ = self?.subscriber?.receive() } } } func cancel() { timer?.invalidate() timer = nil subscriber = nil } }
RepeatingTimePublisher
Publisher
प्रोटोकॉल के अनुरूप है:
import Foundation import Combine final class RepeatingTimerPublisher: Publisher { typealias Output = Void typealias Failure = Never private let interval: TimeInterval private let queue: DispatchQueue init(interval: TimeInterval, queue: DispatchQueue = .main) { self.interval = interval self.queue = queue } func receive<S>(subscriber: S) where S: Subscriber, Failure == S.Failure, Output == S.Input { let subscription = RepeatingTimerSubscription( interval: interval, queue: queue, subscriber: subscriber ) subscriber.receive(subscription: subscription) } }
इस प्रकाशक का उपयोग करने के लिए, आप इसका एक उदाहरण बना सकते हैं और Publisher
प्रोटोकॉल की sink
विधि का उपयोग करके इसकी सदस्यता ले सकते हैं।
उदाहरण के लिए:
private var cancellable: AnyCancellable? func subscribeOnTimer(interval: TimeInterval) { let publisher = RepeatingTimerPublisher(interval: interval) cancellable = publisher.sink { print("Timer fired!") } } //TEST THE METHOD subscribeOnTimer(interval: 5.0)
यह "टाइमर निकाल दिया!" हर 5 सेकंड। आप sink
विधि द्वारा लौटाए गए AnyCancellable
ऑब्जेक्ट पर cancel
विधि को कॉल करके सदस्यता रद्द कर सकते हैं।
उदाहरण के लिए:
deinit { cancellable?.cancel() }
स्विफ्ट में कंबाइन फ्रेमवर्क का उपयोग करके लंबे मतदान को लागू करने के लिए, आप एक प्रकाशक बना सकते हैं जो एक निर्दिष्ट अंतराल पर नेटवर्क अनुरोध करता है, और आउटपुट के रूप में प्रतिक्रिया देता है। आप इसे कैसे कर सकते हैं इसका एक उदाहरण यहां दिया गया है:
विफल मामलों के लिए कस्टम त्रुटि एनम।
enum CustomError: Error { case invalidResponse case invalidDecoding case error }
LongPollingSubscription
Subscription
प्रोटोकॉल के अनुरूप है:
private class LongPollingSubscription<S: Subscriber, Output: Decodable>: Subscription where S.Input == Output, S.Failure == CustomError { private let url: URL private let interval: TimeInterval private let decoder: JSONDecoder private var subscriber: S? private var timer: Timer? private var task: URLSessionDataTask? init( url: URL, interval: TimeInterval, subscriber: S, decoder: JSONDecoder = JSONDecoder() ) { self.url = url self.interval = interval self.subscriber = subscriber self.decoder = decoder } func request(_ demand: Subscribers.Demand) { timer?.invalidate() timer = Timer.scheduledTimer( withTimeInterval: interval, repeats: true ) { [weak self] _ in self?.makeRequest() } makeRequest() } func cancel() { timer?.invalidate() timer = nil task?.cancel() task = nil subscriber = nil } private func makeRequest() { task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in guard let self else { return } if let error = error as? S.Failure { self.subscriber?.receive( completion: .failure(error) ) return } guard let data else { self.subscriber?.receive( completion: .failure(.invalidResponse) ) return } do { let output = try self.decoder.decode( Output.self, from: data ) _ = self.subscriber?.receive(output) } catch { self.subscriber?.receive( completion: .failure(.invalidDecoding) ) } } task?.resume() } }
LongPollingPublisher
Publisher
प्रोटोकॉल के अनुरूप है:
final class LongPollingPublisher<Output: Decodable>: Publisher { typealias Failure = CustomError private let url: URL private let interval: TimeInterval init(url: URL, interval: TimeInterval) { self.url = url self.interval = interval } func receive<S>(subscriber: S) where S: Subscriber, Failure == S.Failure, Output == S.Input { let subscription = LongPollingSubscription( url: url, interval: interval, subscriber: subscriber ) subscriber.receive(subscription: subscription) } }
<Output: Decodable>
का अर्थ है कि आप किसी भी सामान्य प्रकार की प्रतिक्रिया का उपयोग कर सकते हैं जो Decodable
प्रोटोकॉल के अनुरूप हो।
परीक्षण के लिए आपको एक मॉडल बनाने की आवश्यकता है जो Decodable
के अनुरूप हो। मैं https://pixabay.com/api द्वारा एक सार्वजनिक एपीआई का उपयोग करता हूं।
इसे PhotoResponse संरचना होने दें:
struct PhotoResponse: Decodable { struct Photo: Decodable { let user: String let id: Int let largeImageURL: String } let hits: [Photo] let total: Int }
इस प्रकाशक का उपयोग करने के लिए, आप इसका एक उदाहरण बना सकते हैं और Publisher
प्रोटोकॉल की sink
विधि का उपयोग करके इसकी सदस्यता ले सकते हैं। उदाहरण के लिए:
private var cancellable: AnyCancellable? private func pollingTest() { let url = URL(string: "https://pixabay.com/api/?key={your_key}")! let publisher = LongPollingPublisher<PhotoResponse>( url: url, interval: 5.0 ) cancellable = publisher.sink(receiveCompletion: { completion in switch completion { case .finished: print("Completed") case .failure(let error): print("Error: \(error)") } }, receiveValue: { response in print("Received response: \(response)") }) } //TEST THE METHOD pollingTest()
स्विफ्ट में कंबाइन फ्रेमवर्क का उपयोग करके कई उपयोगी कस्टम प्रकाशक बनाए जा सकते हैं। कुछ उदाहरण निम्नलिखित हैं:
NotificationCenterPublisher
केंद्र प्रकाशक: एक प्रकाशक जो अधिसूचना केंद्र पर एक निर्दिष्ट NotificationCenter
पोस्ट किए जाने पर मूल्य उत्सर्जित करता है। आप इस प्रकाशक का उपयोग सिस्टम या ऐप-विशिष्ट घटनाओं, जैसे डिवाइस रोटेशन या नेटवर्क स्थिति परिवर्तन पर प्रतिक्रिया करने के लिए कर सकते हैं।KeyboardPublisher
: एक प्रकाशक जो कीबोर्ड के दिखाए या छिपे होने पर मूल्यों का उत्सर्जन करता है। जब कीबोर्ड प्रस्तुत या खारिज किया जाता है तो आप इस प्रकाशक का उपयोग अपने विचारों के लेआउट को समायोजित करने के लिए कर सकते हैं।CoreLocationPublisher
: एक प्रकाशक जो उपयोगकर्ता के स्थान में परिवर्तन होने पर मूल्यों का उत्सर्जन करता है। इस प्रकाशक का उपयोग उपयोगकर्ता के स्थान को ट्रैक करने और उनके स्थान के आधार पर कार्य करने के लिए किया जा सकता है।UIControlEventPublisher
: एक प्रकाशक जो UIControl या UITextField जैसे UIControl
पर निर्दिष्ट ईवेंट होने पर मान उत्सर्जित करता है। इसका उपयोग प्रतिक्रियात्मक तरीके से उपयोगकर्ता इंटरैक्शन को संभालने के लिए किया जा सकता है।ये ऐसे कस्टम प्रकाशकों के कुछ उदाहरण हैं जिन्हें कम्बाइन फ्रेमवर्क का उपयोग करके बनाया जा सकता है। कुंजी आपके एप्लिकेशन की आवश्यकताओं को समझना और उन आवश्यकताओं को पूरा करने वाले प्रकाशकों को बनाने के लिए फ्रेमवर्क द्वारा उपलब्ध बिल्डिंग ब्लॉक्स का उपयोग करना है।
अंत में, यह ध्यान रखना महत्वपूर्ण है कि कंबाइन फ्रेमवर्क कार्यात्मक प्रतिक्रियाशील प्रोग्रामिंग प्रतिमान का उपयोग करता है, जो एक प्रोग्रामिंग मॉडल है जो समय के साथ घटनाओं की धाराओं से संबंधित है। प्रकाशक, ग्राहकों और ऑपरेटरों के साथ, इस प्रतिमान के मुख्य निर्माण खंड हैं, और वे जटिल और उत्तरदायी अनुप्रयोगों को बनाना आसान बनाते हैं।