I\'m just learning how to use Combine. I have experience with Rx (RxSwift and RxJava) and I\'m noticing that it\'s quite similar.
However, one thing that is quite differ
I had no luck with some Publisher
(annoying restriction).
One option is to use AnyPublisher
:
func a() -> AnyPublisher<(a: Int, b: String), Never> {
return Just((a: 1, b: "two")).eraseToAnyPublisher()
}
func b() -> AnyPublisher {
return a().map(\.b).eraseToAnyPublisher()
}
a().sink(receiveValue: {
let x = $0 // (a: 1, b: "two)
})
b().sink(receiveValue: {
let x = $0 // "two"
})
Alternatively, the "Apple way" (what they use in the standard library) seems to be type aliases (or wrapper structs):
enum PublisherUtils {
typealias A = Just<(a: Int, b: String)>
typealias B = Publishers.MapKeyPath
// or implement a simple wrapper struct like what Combine does
}
func a() -> PublisherUtils.A {
return Just((a: 1, b: "two"))
}
func b() -> PublisherUtils.B {
return a().map(\.b)
}
a().sink(receiveValue: {
let x = $0 // (a: 1, b: "two)
})
b().sink(receiveValue: {
let x = $0 // "two"
})
This is the purpose of the Publishers
namespace in the Combine framework.
Structs are more opaque than type aliases. Type aliases can result in error messages like Cannot convert Utils.MyTypeAlias (aka 'TheLongUnderlyingTypeOf') to expected type ABC
, so the closest you can get to proper opaque types is probably to use a struct, which is essentially what the AnyPublisher
is.