0

I'm looking for a way to prefetch data and cache it without any subscriptions made towards that subscriber or when first subscription is made.

For example :

products = getProducts.shareReply(scope : forever)

And when new subscribers subscribes it should receive the last data. If there is no subscribers it's shouldn't restart this publisher on next subscription instead it should return last cached data.

I'm already using shareReply operator with multicast, custom ReplaySubject and autoconnect but if there is no subscriptions towards the publisher next time something subscribes it will restart the publisher and new data will be fetched. And I don't want that.

This is code for shareReply operator :

extension Publisher {
   
    func shareReplay(_ bufferSize: Int = 1) -> AnyPublisher<Output, Failure> {
        return multicast(subject: ShareReplySubject(bufferSize))
            .autoconnect()
            .eraseToAnyPublisher()
    }
}
harisk92
  • 1,088
  • 1
  • 14
  • 24
  • 1
    Maybe you should look into Subjects like CurrentValueSubject, https://stackoverflow.com/questions/60482737/what-is-passthroughsubject-currentvaluesubject – Joakim Danielson Mar 30 '21 at 08:30
  • @JoakimDanielson I'm aware of it but I would like to turn AnyPublisher to something like Behaviour(CurrentValue)Subject I mean I want to turn anyPublisher to "hot publisher" and so it emits data regardless of if there is a subscriber or not. – harisk92 Mar 30 '21 at 08:55

1 Answers1

0

I'm aware of it but I would like to turn AnyPublisher to something like Behaviour(CurrentValue)Subject I mean I want to turn anyPublisher to "hot publisher" and so it emits data regardless of if there is a subscriber or not.

You can do this by applying the multicast operator and calling connect on the result:

let (sharedProducts, sharedProductsTicket): (AnyPublisher<[Product], Never>, Cancellable) = {
    let pub = getProducts()
        .multicast(subject: CurrentValueSubject([]))
    return (pub.eraseToAnyPublisher(), pub.connect())
}()

Now sharedProducts has a live subscription to getProducts() and stores the latest value published by getProducts(). Anyone who subscribes to sharedProducts immediately receives the latest value, and receives new values as they arrive.

The pub.connect() call returns a Cancellable that, when destroyed, cancels the inner subscription connecting getProducts() to the CurrentValueSubject. So you have to store that ticket somewhere. In my example, I store it in sharedProductsTicket.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848