Creating our own publisher in Combine

Hi,

I have a class or a struct and I would like to make my own publisher that watches a property or the class and publishes its value everytime it changes.


The only way I can think of is to creata a pass through subject and then call 'send' on it everytime the property changes (in the didSend)


but I have a feeling there is probably a better pattern for this that I might be missing? Is there a better way to acheive this? Is there something like the opposite of 'Assign'? that lets you publish changes to a property?

Accepted Reply

Ok, that is a specific question about Combine framework.


Have you read this, there may be interesting information at section @Published usage to bind values to changes :

h ttps://www.avanderlee.com/swift/combine/

Replies

I may be missing your point.


Did you consider having a didSet observer in the class for the var you want to observe.


This could in turn post a notification for otrher objects to subscribe to ?

Thanks Claude31,

So you mean firing a a notification inside the didSet. Then you can get a publisher by calling publisher(for:object:) method on NotificationCenter to get a publisher that would fire every time the property changes.


I guess that should work too. But I am wondering if there there is a 'recommended' way or design pattern for this. For example is there any benifit in using a notification center instead of a passthrough subject? Or is there a simpler way out there? Because to me it sounds like such a common use case that there should be something like the 'complement' of 'assign'. Assign subcribes to a publisher and updates a property of an object. So I was just wondering if there is something that fits the other side of the equation where you have a simple way to expose a property on a class as a publisher.

I think PassthroughSubject() may actually be one of the easiest routes, depending on how, when and what you want to send. If you're creating a one-shot publisher (single or limited set of values, transmitted on demand) then the built-in publishers have a lot of value (Once, Just, Sequence, etc).


But if you've got some interactive code, or your trying to a stream of values responses back from existing code, then using the PassthroughSubject().send() may be a godsend. There's not really another generic "publisher factory" in the Combine API.


Worth mentioning, on Github there's a new project meant to include some helper pieces to Combine: Entwine. https://github.com/tcldr/Entwine/blob/master/Assets/Entwine/README.md includes a method Publisher.Factory(https://tcldr.github.io/Entwine/EntwineDocs/Extensions/Publishers/Factory.html)that may do exactly what you're after.

Ok, that is a specific question about Combine framework.


Have you read this, there may be interesting information at section @Published usage to bind values to changes :

h ttps://www.avanderlee.com/swift/combine/

Yes @published semes to be the 'complement' of assign indeed. Thanks for pointing that out