If I have an array:
var arr = [0,1,2]
And a Combine publisher for it:
arr.publisher
.sink { completion in print("Completed with \(completion)")
} receiveValue: { val in
print("Received value \(val)")
}
arr.append(3)
Why does it finish right away with:
Received value 0
Received value 1
Received value 2
Completed with finished
How can I make Combine execute the code every time I append values to the array?
CodePudding user response:
The publisher
method of the array does exactly that - emits every element of the array and then completes, because the array at the time of calling the publisher has a finite number of elements.
If you want to be notified every time the arrays changes (not just when something is appended to it, but on any change) then create a @Published var
for the array and attach the observer to it:
@Published var arr = [1,2,3]
cancellable = $arr
.sink { completion in print("Completed with \(completion)")
} receiveValue: { val in
print("Received value \(val)")
}
arr.append(4)
The output will be:
Received value [1, 2, 3]
Received value [1, 2, 3, 4]
But looks like what you are really looking for is listening to a stream of numbers emitted one at a time. Then define a @Published var
of that type and listen to it. You'll get called every time the var changes:
@Published var value = 1
cancellable = $value
.sink { completion in print("Completed with \(completion)")
} receiveValue: { val in
print("Received value \(val)")
}
value = 2
value = 3
value = 4
The output will be:
Received value 1
Received value 2
Received value 3
Received value 4