Swift Combine API client; return Future or AnyPublisher?

I'm implementing (for the first time) a web service client in Swift using the Combine framework.

For a method that makes a single call to a web service and then closes the connection, what is considered best practice – to return a Future or a Publisher?

Code Block
func getSomeThing() -> Future<SomeThing...> { }

Code Block
func getSomeThing() -> AnyPublisher<SomeThing...> { }

In Flutter, a single async value would be a "Future" and multiple async values would be a "Stream". In the WWDC 2019 talk: "Introducing Combine" Apple presents a slide that hints at Futures as the async version of a single sync value. And Publishers as the async version of sync arrays.

I understand that Futures in fact are Publishers. And that there may be some subtle technical nuances to consider (greedy/lazy etc).

But thinking about the communicated intent, returning a Future seems to indicate a one hit wonder pipeline better than returning an AnyPublisher. But returning a Publisher seems easier and more in line with the framework, since it's pretty easy to eraseToAnyPublisher, for example from an URLSession.DataTaskPublisher, and just return that object.

Mapping a DataTaskPublisher pipeline to a Future dosen't seem to be straight forward at all.

Any best practice advise would be appreciated.
  • I don't have a definite answer on what the best practice is, but have wondered the same thing. In the past, I would return a Future. Now, I always return type-erased AnyPublisher. I find it keeps the interface more general, seems cleaner (standard) and, like you said, often it's easier to work. Besides, the type-erased Future returned as AnyPublisher is still going to finish after one output.

Add a Comment