Home > front end >  How to have Combine subscriber finish upon receiving specific value
How to have Combine subscriber finish upon receiving specific value

Time:05-21

I'm trying to use a Combine subscriber to wait for a specific value from a publisher, which seems easy enough if I handle the values in sink(receiveValue:), but I want to convert the publisher to another publisher that just finishes when the specific value is received.

This is the code that works:

let publisher: AnyPublisher<Int, Never> = ...

let cancellable = publisher.sink(receiveValue: { value in
    if value == myFavoriteNumber {
        // we're finished!
    }
})

What I'm trying to accomplish is something like this:

let modifiedPublisher: AnyPublisher<Never, Never> = publisher.compactMap({ 
    $0 == myFavoriteNumber ? Publishers.Completion.finished : nil 
}).eraseToAnyPublisher()

Is there a way to do this?

CodePudding user response:

The solution I came up with uses the tryPrefix operator:

let FavoriteNumber = 42
let publisher: AnyPublisher<Int, Never> = (0...360).publisher.eraseToAnyPublisher()

let upToFavoriteNum = publisher.tryPrefix {
    $0 != FavoriteNumber
}

let subscription = upToFavoriteNum.sink(receiveCompletion: {
    completion in
    debugPrint(completion)
}, receiveValue: {
    print("processing \($0)")
})
  • Related