Skip to content

Instantly share code, notes, and snippets.

@SwiftedMind
Last active March 27, 2023 08:25
Show Gist options
  • Save SwiftedMind/4c321b5c73ceb4b792fec1f52ca9b5e9 to your computer and use it in GitHub Desktop.
Save SwiftedMind/4c321b5c73ceb4b792fec1f52ca9b5e9 to your computer and use it in GitHub Desktop.
Puddles Architecture - Queryable Demo
import SwiftUI
import Puddles
struct Item: Identifiable {
var id = UUID()
var name: String
static var draft: Self { .init(name: "") }
}
@MainActor
final class ItemStore: ObservableObject {
@Published var items: [Item] = []
}
import SwiftUI
import Puddles
struct RootNavigator: View {
// In-memory item store used for the demonstration
@StateObject private var itemStore = ItemStore()
// Queryable<InputType, ResultType>
@Queryable<Item, Item?> private var itemCreation
var body: some View {
List {
ForEach(itemStore.items) { item in
Text(item.name)
}
Button("Create Item") {
queryItemCreation()
}
}
// Define a sheet that is controlled by the queryable.
.queryableSheet(controlledBy: itemCreation) { item, query in
// Define the contents and make sure to answer the query at some point
EditItemView(initialDraft: item) { createdItem in
query.answer(withOptional: createdItem)
}
}
}
@MainActor
private func queryItemCreation() {
Task {
do {
// Triggers the presentation of a sheet with an `EditItemView` to create an item and a save button.
// When the save button has been pressed, the sheet is dismissed and
// this function resumes with the created item.
if let item = try await itemCreation.query(with: .draft) {
itemStore.items.append(item)
print("Created \(item)")
} else {
print("Cancelled item creation")
}
} catch {
print(error)
}
}
}
}
// MARK: - EditItemView
struct EditItemView: View {
@State private var draft: Item
private var onCompletion: (_ item: Item?) -> Void
init(initialDraft: Item, onCompletion: @escaping (_ item: Item?) -> Void) {
self._draft = .init(initialValue: initialDraft)
self.onCompletion = onCompletion
}
var body: some View {
List {
VStack {
TextField("Name", text: $draft.name)
Button("Cancel", role: .cancel) {
onCompletion(nil)
}
.buttonStyle(.bordered)
Button("Save") {
onCompletion(draft)
}
.buttonStyle(.borderedProminent)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment