Skip to content

Instantly share code, notes, and snippets.

@maxgribov
Last active December 16, 2023 20:44
Show Gist options
  • Save maxgribov/3cf22cd41359ea5195ea777182afffe1 to your computer and use it in GitHub Desktop.
Save maxgribov/3cf22cd41359ea5195ea777182afffe1 to your computer and use it in GitHub Desktop.
Swift async api adoption
import Foundation
import Combine
struct Page<Item> {
typealias LoadMoreCompletion = (Result<[Item], Error>) -> Void
let items: [Item]
let loadMore: (@escaping LoadMoreCompletion) -> Void
init(items: [Item], loadMore: @escaping (@escaping LoadMoreCompletion) -> Void) {
self.items = items
self.loadMore = loadMore
}
}
//MARK: - Combine
extension Page {
var loadMorePublisher: () -> AnyPublisher<[Item], Error> {
return {
Deferred { Future(loadMore) }.eraseToAnyPublisher()
}
}
init(items: [Item], loadMorePublisher: @escaping () -> AnyPublisher<[Item], Error>) {
self.init(items: items, loadMore: { completion in
loadMorePublisher()
.subscribe(Subscribers.Sink(receiveCompletion: { result in
if case let .failure(error) = result {
completion(.failure(error))
}
}, receiveValue: { value in
completion(.success(value))
}))
})
}
}
//MARK: - Swift Concurrency
extension Page {
var loadMoreAsync: () async throws -> [Item] {
{
try await withCheckedThrowingContinuation { continuation in
loadMore(continuation.resume(with:))
}
}
}
init(items: [Item], loadMoreAsync: @escaping () async throws -> [Item]) {
self.init(items: items, loadMore: { completion in
Task {
do {
let result = try await loadMoreAsync()
completion(.success(result))
} catch {
completion(.failure(error))
}
}
})
}
}
let pageSample = Page(items: []) { completion in
completion(.success(["result"]))
}
let pageSampleCombine = Page(items: [], loadMorePublisher: pageSample.loadMorePublisher)
let pageSampleAsync = Page(items: [], loadMoreAsync: pageSampleCombine.loadMoreAsync)
pageSampleAsync.loadMore { completion in
print(completion)
// success(["result"])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment