0

I have an event bus that publishes events happening over a custom text field(a chat message input box), like attachMediaEvent, sendMessageEvent, selectTextEvent. I want to provide provide default actions for the events, but only in case downstream doesn't handle it(kind of like how one can provide protocol default implementation). Is there a way to check if the downstream handles the event and handle it if doesn't?

I know that I'm being loose with the phrase handling the event but it was intentional and I would like any sort of solution for it. And I'm not adding any code, but I can do so, if needed. It is a really simple publisher that pushes events, anyhow.

EDIT: Ok, I dug deeper in SO and I started to get the idea that I had to implement custom operator. But I have hit the exact same roadblock. I have no idea how a downstream can speak to the upstream about how it has handled its values. Although I tried to create a protocol(EventConsumer) that one could check if implemented by a object that is passed to the subscriber, but which felt very wrong. Any help would be a godsend.

Here's the code I tried in playground.

@objc protocol EventConsumer {

    @objc optional func sendEventAction()
    @objc optional func attachEventAction()
}
    
class DefaultEventConsumer: EventConsumer {

}

struct CustomPublisher<Upstream: Publisher>: Publisher where Upstream.Output == String, Upstream.Failure == Never {
    
    typealias Output = String
    
    typealias Failure = Never
    
    var upstreamEventPublisher: Upstream
//    var eventConsumer: EventConsumer
    
    func receive<S>(subscriber: S) where S : Subscriber, Never == S.Failure, String == S.Input {
        
        let subscription = CustomSubscription<S>(/*eventHandler: eventConsumer*/)
        subscription.downstream = subscriber
        
        subscriber.receive(subscription: subscription)
        
        upstreamEventPublisher.sink { eventString in
            
            subscription.sendEvent(event: eventString)
        }
    }
}

class CustomSubscription<Downstream: Subscriber>: Subscription where Downstream.Input == String {
    
    var downstream: Downstream?
//    var eventHandler: EventConsumer
    
//    init(eventHandler: EventConsumer) {
//        self.eventHandler = eventHandler
//    }
    
    func request(_ demand: Subscribers.Demand) {
    }

    func cancel() {

        downstream = nil
    }
    
    func sendEvent(event: String) {
        
        //How do I check if downstream processes the event somehow and send event if it doesnt
        downstream?.receive(event)
    }
}
//
//
//extension AnyPublisher where Output == String, Failure == Never {
//
//    func checkAndPublishEvents(_ eventConsumer: EventConsumer) -> Self {
//
//        CustomPublisher(upstreamEventPublisher: self/*, eventConsumer: eventConsumer*/)
//            .eraseToAnyPublisher()
//    }
//}
Aswath
  • 1,236
  • 1
  • 14
  • 28
  • Someone has voted to close the question. This might be a duplicate or missing details/ code or simply a dumb question. But honestly, I have no idea. If only you could be kind enough to let me know why. – Aswath Aug 05 '21 at 12:24
  • You might not be thinking about Combine correctly. Combine allows you to manipulate a series of values emitted over time. A publisher emits events based on demand from the subscriber - there's no other method of communication that's built into Combine. Clarify what you're trying to achieve - Combine might not even be what you need. – New Dev Aug 05 '21 at 17:41
  • @NewDev I need a publisher that publishes values, but the downstream could control what is being published from the upstream. If Combine cannot achieve that, fine, but that's pretty much what I want – Aswath Aug 05 '21 at 18:24
  • The downstream operators could augment what they receive from the upstream when they publish their own values, or could publish something else in response to each upstream value. That's what Combine *is* for. But the way you asked implied that the very values that are being emitted from upstream are somehow controlled by a downstream. – New Dev Aug 05 '21 at 19:32
  • Still, your question is too broad as asked. That's also why there was a close vote. I'd suggest adding a concrete example (even if doesn't compile; or even if it's not even code) of what you mean by "control what is being published from the upstream" – New Dev Aug 05 '21 at 19:34
  • @NewDev i thought my bit of code could illustrate what I was trying to do. But, I cannot add a concrete example in code, because I do not know how, which is why I am asking this question. It seems that it might not be possible to do it in Combine. Thanks for your help – Aswath Aug 06 '21 at 02:45
  • I meant, a concrete example of what "processing an event" (as per comment in your code), or what "control what is being published" (as per your comment above) actually means. An example could be a series of values from upstream and what downstream is supposed to receive or affect. Alternatively, what are you trying to accomplish (aside from code) - you might be asking about an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – New Dev Aug 06 '21 at 12:54
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/235697/discussion-between-aswath-and-new-dev). – Aswath Aug 06 '21 at 14:00

0 Answers0