Reputation: 24884
I am using Combine with Swift5; I have a CurrentValueSubject
that I am combining with a @Published
dictionary variable.
The problem is that when the current value is updated, map never gets called! This is specifically an issue with @Published
variable since it works with other streams that are not using @Published
.
@Published var userModels: [String: UserModel] = [:]
var chatModels: CurrentValueSubject<[ChatModelFirebase], Never> = CurrentValueSubject([])
chatModels
.combineLatest(userModels.publisher)
.map({ (chatModels, userModels) -> [ChatViewModel] in
print("Hello") // Never gets called! 😢
return []
})
.assign(to: \.chatViewModels, on: self)
.store(in: &cancellableSet)
// Update chat model's value, and notice that map never gets called!
chatModels.values = []
There are no errors, code compiles and runs, but I never get the results of stream updates. The problem will be fixed if I update userModels
to also be CurrentValueSubject
, but the question is why is combineLatest(..)
breaking with @Published
?
Upvotes: 0
Views: 1567
Reputation: 49590
I think you're confusing between two publishers: the Published<Value>.Publisher
publisher created from a @Published
property via $userModels
and the Publishers.Sequence
publisher that you get from userModels.publisher
.
The Published
one publishes the value on every change. So, $userModels
would publish the the [:]
value right away, and then again with every change:
class Foo {
@Published var dict: [String: Int] = [:]
}
let foo = Foo()
foo.$dict
.sink { print($0) }
foo.dict = ["one": 1, "two": 2]
the output is:
[:]
["one": 1, "two": 2]
The Sequence
publisher publishes each value from a sequence, which for a dictionary is a series of tuples of (key, value)
. For an empty sequence, it publishes no values:
var dict: [String: Int] = [:]
dict.publisher
.sink { print($0) } // will not print anything
In your case, you're using .combineLatest
with a Sequence
publisher from an empty dictionary, which publishes no values, and so CombineLatest
publishes no values.
What you might have be looking for was to subscribe to a Published
publisher of userModels
property:
chatModels.combineLatest($userModels)
.sink { print($0) }
the initial output then would immediately be:
([:], [])
Upvotes: 1