Skip to content

Commit

Permalink
MMMLoadable: add async/await helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
aleh committed Jan 22, 2024
1 parent b4a5bed commit f60c253
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
2 changes: 1 addition & 1 deletion MMMLoadable.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Pod::Spec.new do |s|

s.name = "MMMLoadable"
s.version = "2.0.0"
s.version = "2.1.0"
s.summary = "A simple model for async calculations"
s.description = "#{s.summary}."
s.homepage = "https://github.com/mediamonks/#{s.name}"
Expand Down
28 changes: 28 additions & 0 deletions Sources/MMMLoadable/MMMLoadable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,34 @@ extension MMMPureLoadableProtocol {
block(self)
}
}

/// Waits for the receiver to stop syncing and continues if `isContentsAvailable`; throws otherwise.
public func doneSyncing() async throws {
try await contentsAfterDoneSyncing { _ in }
}

/// Waits for the receiver to stop syncing; then, if `isContentsAvailable`, returns the result of the given closure;
/// throws otherwise.
public func contentsAfterDoneSyncing<T>(_ grabContents: @escaping (Self) throws -> T) async throws -> T {
try await withCheckedThrowingContinuation { continuation in
DispatchQueue.main.async {
var waiter: MMMSimpleLoadableWaiter?
waiter = MMMSimpleLoadableWaiter.whenDoneSyncing(self) {
do {
if self.isContentsAvailable {
continuation.resume(returning: try grabContents(self))
} else {
throw self.error ?? NSError(domain: self, message: "Unspecified error")
}
} catch {
continuation.resume(throwing: error)
}
// We need to keep the waiter around while waiting.
_ = waiter
}
}
}
}
}

/// Forwards all calls in `MMMPureLoadableProtocol` to another object.
Expand Down

0 comments on commit f60c253

Please sign in to comment.