Swift
[Swift, Combine] AnyPublisher 를 async/await throws 로 사용해보자
insub4067
2023. 10. 4. 09:47
https://developer.apple.com/documentation/swift/withcheckedthrowingcontinuation(function:_:)
withCheckedThrowingContinuation(function:_:) | Apple Developer Documentation
Invokes the passed in closure with a checked continuation for the current task.
developer.apple.com
import Foundation
import Combine
extension AnyPublisher where Failure: Error {
var asyncThrows: Output {
get async throws {
try await withCheckedThrowingContinuation { continuation in
var cancellable: AnyCancellable?
cancellable = first()
.sink { completion in
switch completion {
case .finished:
break
case .failure(let error):
continuation.resume(throwing: error)
}
cancellable?.cancel()
} receiveValue: { value in
continuation.resume(with: .success(value))
}
}
}
}
}
import Foundation
import Combine
struct UserNetwork {
private let network: Networkable
private let baseUrl = "https://api.github.com/users/"
private var url: (String) -> URL {{ query in URL(string: baseUrl + query)! }}
init(network: Networkable = Network()) {
self.network = network
}
func getUser(username: String) -> AnyPublisher<User, Error> {
network.request(url: url(username))
}
}
func didTapButton() {
// AnyPublisher -> async throws
Task {
let user = try? await userNetwork.getUser(username: "insub4067").asyncThrows
print(user)
}
// AnyPublisher
userNetwork.getUser(username: "insub4067")
.sink { completion in
guard let error = completion.networkError else { return }
switch error {
case .badResponse:
print(error)
case .statusCode(let status):
print(error, status)
case .badUrl:
print(error)
case .unknown:
break
}
} receiveValue: { user in
print(user)
}
.store(in: &cancellable)
}