Last active
March 27, 2023 08:25
-
-
Save SwiftedMind/4c321b5c73ceb4b792fec1f52ca9b5e9 to your computer and use it in GitHub Desktop.
Puddles Architecture - Queryable Demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] = [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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