Search code examples
iosios13combine

Combine framework third `collect` method


In the iOS 13 Combine framework, there are three collect operator methods. The first two are obvious but the third uses types I can't figure out.

 collect(_:options:)

https://developer.apple.com/documentation/foundation/timer/timerpublisher/3329497-collect

func collect<S>(_ strategy: Publishers.TimeGroupingStrategy<S>, 
    options: S.SchedulerOptions? = nil) 
    -> Publishers.CollectByTime<Timer.TimerPublisher, S> 
    where S : Scheduler

Can anyone give an example of how one would call this method?


Solution

  • After some struggle, I came up with an example like this:

    let t = Timer.publish(every: 0.4, on: .main, in: .default)
    t
        .scan(0) {prev,_ in prev+1}
        .collect(.byTime(DispatchQueue.main, .seconds(1))) // *
        .sink(receiveCompletion: {print($0)}) {print($0)}.store(in:&storage)
    let cancellable = t.connect()
    delay(3) { cancellable.cancel() }
    

    (where storage is the usual Set<AnyCancellable> to keep the subscriber alive).

    The output is:

    [1, 2]
    [3, 4, 5]
    [6, 7]
    

    So we are publishing a new number about every 0.4 seconds, but collect only does its thing every 1 second. Thus, the first two values arrive, publishing 1 and 2, and then collect does its thing, accumulates all the values that have arrived so far, and publishes them as an array, [1,2]. And so on. Every second, whatever has come down the pipeline so far is accumulated into an array and published as an array.