SwiftUI's pull-to-refresh functionality requires an operation that uses structured concurrency (async/await) to indicate to the UI when the refreshing is complete. This controls the animation of the refresh indicator. Currently, VSM does not directly support a mechanism for awaiting a specific state in a structurally concurrent context.
Add an async observe overload that allows the engineer to wait for a specific state using Swift Concurrency. When the view state is detected, the function should return, which will complete the refresh animation. If the view state is not hashable, a closure can be provided to test the state's equality.
Hypothetical Example
List(model.conversations) { conversation in
ConversationCell(conversation)
}
.refreshable {
await $state.observe(
model.refresh(),
until: { state in
if case .loaded(_) = state {
return true
}
return false
}
)
}
Alternatives Considered
Creating a refreshable overload in an extension on relevant SwiftUI types that relies on a Binding instead of swift concurrency. (Tangent: This is the API that the SwiftUI team should have used.)
Example
List(mailbox.conversations) { conversation in
ConversationCell(conversation)
}
.refreshable($isRefreshing)
This is a less-favored solution because it deviates the engineer from Apple's frameworks and creates a standard that can be confusing to many.
Additional Context
refreshable's tech design is an interesting move from the SwiftUI team in choosing a swift concurrency approach in a library that is otherwise almost exclusively driven by observability (KVO, Publishers, and Bindings). It's hard to tell if this is a new pattern that we will see more of, or a small digression in an otherwise largely declarative/observable framework.
Problem Statement
SwiftUI's pull-to-refresh functionality requires an operation that uses structured concurrency (async/await) to indicate to the UI when the refreshing is complete. This controls the animation of the refresh indicator. Currently, VSM does not directly support a mechanism for awaiting a specific state in a structurally concurrent context.
Example
Proposed Solution
Add an async
observe
overload that allows the engineer to wait for a specific state using Swift Concurrency. When the view state is detected, the function should return, which will complete the refresh animation. If the view state is not hashable, a closure can be provided to test the state's equality.Hypothetical Example
Alternatives Considered
Creating a
refreshable
overload in an extension on relevant SwiftUI types that relies on aBinding
instead of swift concurrency. (Tangent: This is the API that the SwiftUI team should have used.)Example
This is a less-favored solution because it deviates the engineer from Apple's frameworks and creates a standard that can be confusing to many.
Additional Context
refreshable
's tech design is an interesting move from the SwiftUI team in choosing a swift concurrency approach in a library that is otherwise almost exclusively driven by observability (KVO,Publisher
s, andBindings
). It's hard to tell if this is a new pattern that we will see more of, or a small digression in an otherwise largely declarative/observable framework.