Swiftpack.co - petrpavlik/CombineToAsyncAwait as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by petrpavlik.
petrpavlik/CombineToAsyncAwait 1.2.0
Convenience APIs to make Combine publishers async.
⭐️ 11
🕓 2 years ago
iOS macOS
.package(url: "https://github.com/petrpavlik/CombineToAsyncAwait.git", from: "1.2.0")

CombineToAsyncAwait

Adds try await myCombineStream.firstValue, await myCombineStream.firstResult and await myCombineStream.completed() for convenient usage because there is no Apple-provided API for it, only to turn a Combine stream into AsyncStream using .values.

You can use JohnSundell/AsyncCompatibilityKit to have .values backported to iOS 13 and related macOS.

Example

Let's convert a Combine publisher provided by Apple to make a network request into async/await

Combine implementation

URLSession.shared.dataTaskPublisher(for: url).sink { completion in
    // check error
} receiveValue: { value in
    // process value
}.store(in: &cancellables)

Async/await bridge

import CombineToAsyncAwait

extension URLSession {
    func data(for url: URL) async throws -> (Data, URLResponse) {
        try await self.dataTaskPublisher(for: url).firstValue
    }
}

final class NetworkingTests: XCTestCase {
    func testNetworkRequest() async throws {
        let (data, response) = try await URLSession.shared.data(for: URL(string: "https://google.com")!)
    }
}

Note: Apple has actually introduced async/await versions of this as a part of foundation on iOS 15 and corresponding OSes, so this is only to demonstrate how easy it is to turn a Combine publisher into an async method.

Keeping the Error Type

One of the disadvantages of async/await is that the error gets erased, you can use firstResult instead that returns a Result type where the error type matches the combine publisher.

let result = await myApiProvider.userProfile(id: 123).firstResult
switch result {
case .success(let user):
    // ...
case .failure(let fetchUserError):
    switch fetchUserError {
    case .notFound:
        // ...
    }
}

Await Stream Completion

For streams of void value, you may want to await stream completion instead of a value.


See this package and thousands of others on swiftpack.co

GitHub

link
Stars: 11
Last commit: 2 years ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Release Notes

1.2.0
2 years ago

Add APIs to await stream completion.

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics