Skip to content

Swift @propertyWrapper that waits asynchronously until the value matches a predicate.

License

Notifications You must be signed in to change notification settings

swhitty/Awaiting

Repository files navigation

Build Codecov Platforms Swift 5.7 License Twitter

Introduction

@Awaiting is a Swift @propertyWrapper that waits asynchronously until the value matches a predicate.

Usage

Any class can declare a property to be @Awaiting as follows:

@Awaiting var isComplete: Bool = false

You then use its projected value to await until some predicate is met;

// Suspends until isComplete == true
_ = try await $isComplete.first(where: { $0 == true })

Cancellation

CancellationError is thrown if the task is cancelled before the predicate is met.

Optionals

When optionals are wrapped you can wait for the first non nil value:

@Awaiting var name: String?

// Suspends until name != nil
let name = try await $name.some()

Equatables

When equatables are wrapped you can wait for the first value that equals an element:

@Awaiting var name: String?

// Suspends until name == "Fish"
try await $name.equals("Fish")

Collections

When collections are wrapped you can wait for an element to exist at an index:

@Awaiting var names = [String]()

// Suspends until names[2] exists
let name = try await $names.element(at: 2)

Or wait for an element that matches the predicate:

// Suspends until a name contains an element that contains 5 or more letters
let name = try await $names.element { $0.count > 5}

Or wait for at least n elements to exist:

// Suspends until names.count >= 3
let nonEmpty = try await $names.first(withAtLeast: 3)

Credits

@Awaiting is primarily the work of Simon Whitty.