Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine: Publisher like Future but with multiple values

I have 3d party library (Firestore) that has this method

func listenToEvents(handler: ([Result], Error) -> Void)

handler in this method is called many times (after any updates of the data). I want to convert it to Publisher

Here is my code now:

var resultsPublisher: AnyPublisher<[Result], Error> {
    Deferred { 
        Future { promise in
           libraryObject.listenToEvents { results, error in // called multiple times
              guard let results = results else {
                 promise(.failure(error))
                 return
              }

              // this can't be called several times,
              // because Future's promise is supposed to be called only once
              promise(.success(results))
           }
         }
    }
    .eraseToAnyPublisher()
}

So my Publisher produces value only once, because Future works this way. Are there any other Publishers (or may be a different approach) to accomplish that?

like image 589
Paul T. Avatar asked Oct 28 '25 08:10

Paul T.


1 Answers

Here is possible alternate approach. No needs in Defer, 'cause subject lives idle, and can send (pass-through) as many values as libraryObject will live.

Tested with Xcode 11.4.

var resultsPublisher: AnyPublisher<[Result], Error> {
    let subject = PassthroughSubject<[Result], Error>()
    libraryObject.listenToEvents { results, error in // called multiple times
        guard let results = results else {
            subject.send(completion: .failure(error))
            return
        }

        subject.send(results)
    }
    return subject.eraseToAnyPublisher()
}
like image 173
Asperi Avatar answered Oct 30 '25 23:10

Asperi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!