AsyncLoadableStream

Listen to an AsyncLoadable by using an AsyncStream. This allows you to iterate over the iterator, this will stream a new AsyncLoadableStreamObject on every change in the loadable.

For example:

class MyView: UIView {

    private let loadable: AsyncLoadable<MyData>

    // It's crucial that we call `finish()` somehow, this is also called upon deinit,
    // so storing it as a property is an easy way to accomplish this.
    private var stream: AsyncLoadableStream<MyData>?

    public init(loadable: AsyncLoadable<MyData>) {

        let stream = AsyncLoadableStream(loadable)

        self.loadable = loadable
        self.stream = stream

        for await obj in stream.iterator {
            // Do something with the stream object, e.g. update UI.
            updateUI()
        }
    }

    private func updateUI() {
        loader.isHidden = loadable.loadableState != .syncing
    }
}

Please note that due to the nature of async/await in swift it’s crucial to store the stream as a local (private) property to ensure that finish() get’s called upon deinit. This stops the stream. Otherwise your Actor will get blocked indefinitely, since it will keep on waiting for new values, causing a memory leak.

  • The iterator to loop over, e.g. using a for await val in stream.iterator { ....

  • Initialise a new stream.

  • Finish the stream, this stops the for await loop. This is required to call somewhere, either by deinit (via a stored property) or manually.