Search code examples
swiftcombine

How to use Swift and Combine to publish results of calls to a function with coded termination logic?


I’m curious, how do we use Combine to publish the results of a function until a certain answer is received?

For the purposes of this example, let’s say I’m using this function:

func guessANumber() -> Int { Int.random(in: 0...9) }

I want to use Combine to publish a sequence of results from this function that will terminate when it receives zero as the output. How do I achieve that?


Solution

  • You can just create a lazy Sequence that does that, using sequence.

    let seq = sequence(first: guessANumber()) { _ in
        let number = guessANumber()
        return number == 0 ? nil : number
    }
    

    If you really want, you can turn this into a Publisher using the publisher property:

    let publisher = seq.publisher
    

    Alternatively, make an infinite sequence, and use the prefix(while:) operator:

    sequence(first: guessANumber()) { _ in guessANumber() }
        // .publisher // prefix(while:) is also a Combine operator
        .prefix(while: { $0 != 0 })