Search code examples
swiftcombinepublisher

How do you run a Swift Combine Publisher for a certain amount of time?


I have a publisher when the sink, scans for a list of wifi. I only want to scan for about 10 seconds and stop.

Is there a way to do this within the publisher chain of calls?


Solution

  • This operator will do the trick.

    import PlaygroundSupport
    import Foundation
    import Combine
    
    let page = PlaygroundPage.current
    page.needsIndefiniteExecution = true
    
    extension Publisher {
        func stopAfter<S>(_ interval: S.SchedulerTimeType.Stride, tolerance: S.SchedulerTimeType.Stride? = nil, scheduler: S, options: S.SchedulerOptions? = nil) -> AnyPublisher<Output, Failure> where S: Scheduler {
            prefix(untilOutputFrom: Just(()).delay(for: interval, tolerance: tolerance, scheduler: scheduler, options: nil))
                .eraseToAnyPublisher()
        }
    }
    
    let source = Timer.publish(every: 1, tolerance: nil, on: RunLoop.main, in: .default, options: nil)
        .autoconnect()
        .eraseToAnyPublisher()
    
    let cancellable = source
        .stopAfter(10, scheduler: DispatchQueue.main)
        .sink(receiveValue: { print($0) })