Home > Enterprise >  Turning function that has a combination of publishers/sinks into an async function
Turning function that has a combination of publishers/sinks into an async function

Time:12-31

I have the following function loadData and I want to use it within refreshable of a SwiftUI list. For this I need to make it an async function:

func loadData() {
  // Publishers
  let followersPublisher = modelLoader.loadAllFollowers(withId: id)
  let followingPublisher = modelLoader.loadAllFollowing(withId: id)
  let friendshipsPublisher = Publishers.Zip(followersPublisher, followingPublisher)
    .share()
    .eraseToAnyPublisher()

  // Sinks
  getFollowers(from: followersPublisher)
  getFollowerChange(
    from: followersPublisher,
    cachedFollowers: followers
  )
  getFollowing(from: followingPublisher)
  getNotFollowingUserBack(from: friendshipsPublisher)
  getUserNotFollowing(from: friendshipsPublisher)

  followersPublisher
    .connect()
    .store(in: &cancellables)
  followingPublisher
    .connect()
    .store(in: &cancellables)
}

Within this function, all the separate functions use Publisher sinks. For example:

private func getFollowing(from publisher: Publishers.MakeConnectable<AnyPublisher<Set<User>, Never>>) {
  publisher
    .sink(
      receiveCompletion: { _ in },
      receiveValue: { [weak self] following in
        self?.following = following
      }
    )
    .store(in: &cancellables)
}

How can I turn it into an async function so I can use await with it?

CodePudding user response:

Every Combine Publisher has a values property that is an async sequence:

https://developer.apple.com/documentation/combine/publisher/values-1dm9r

Thus any pipeline that starts with a Publisher can be replaced by async/await code, capturing the values using an async for loop. So if you want to, you could keep on using your followersPublisher and your followingPublisher and just subscribe to them using async/await instead of Combine.

On the other hand, depending what those publishers do, you might want to follow this chain further back and get rid of those publishers and replace them by async methods that you can call from an async/await context.

  • Related