Hey,
I've been working on something for the past few months that allows you to use Swift's concurrency mechanism to trigger any kind of SwiftUI view presentation and await
its completion/result, similar to calling an async
function, but with UI as the "asynchronous" part.
I'm calling it Queryable: GitHub - SwiftedMind/Queryable: Asynchronous view presentations in SwiftUI
Example
To better explain what it does, here is a simple example:
import SwiftUI
import Queryable
struct ContentView: View {
// Empty input type and Bool as the result type
@Queryable<Void, Bool> var buttonConfirmation
var body: some View {
Button("Commit", action: confirm)
.queryableAlert(controlledBy: buttonConfirmation, title: "Really?") { item, query in
Button("Yes") { query.answer(with: true) }
Button("No") { query.answer(with: false) }
} message: {_ in}
}
@MainActor
private func confirm() {
Task {
do {
let isConfirmed = try await buttonConfirmation.query()
// Do something with the result
} catch {}
}
}
}
This is a view with a single button. When you tap it, an iOS alert should be shown with a "Yes" and a "No" button to confirm or cancel the action. The alert presentation is controlled by a buttonConfirmation
property, which completely hides the state logic required to do this.
All you have to do is call buttonConfirmation.query()
. from any asynchronous context (doesn't even have to be from within the same view). That function will suspend the current Task, show the alert and then resume with the result, once the user has tapped on one of the buttons. This nicely integrates any kind of UI into asynchronous code. The entire view presentation is compressed into a single function call: query()
.
This not only works with alert
, but also with confirmationDialog
, sheet
, fullScreenCover
and fully custom overlay views.
Get Started
You'll find more information and details in the "Get Started" section of the repository's readme. And if you want to see it used inside an app, have a look at SwiftedMind/Scrumdinger, which is a re-implementation of Apple's SwiftUI tutorial app with an app architecture I'm currently working on for fun (the guys from pointfree had the awesome idea to use Apple's example app and re-implement it using different techniques, so that is my attempt at it ).
I'm genuinely curious what people think of this. I'm still not completely sure if this entire idea is a terrible anti-pattern or an actually useful tool for building SwiftUI apps.
Have a great day!