Post

Replies

Boosts

Views

Activity

MacOS SwiftUI access modelContext from menu (.commands)?
Adding an Import... menu item using .commands{CommandGroup... on DocumentGroup( ... ) { ContentView() } .commands { CommandGroup(replacing: .importExport) { Button("Import…") { isImporting = true } .keyboardShortcut("I", modifiers: .option) .fileImporter( isPresented: $isImporting, allowedContentTypes: [.commaSeparatedText], allowsMultipleSelection: false ) { result in switch result { case .success(let urls): print("File import success") ImportCSV.importCSV(url: urls, in: context) // This is the issue case .failure(let error): print("File import error: \(error)") } } } I could get this to work if I were not using DocumentGroup but instead programmatically creating the modelContext. using the shared modelContext in ImportCSV is not possible since that is not a View passing the context as shown above would work if I knew how to get the modelContext but does it even exist yet in Main? Is this the right place to put the commands code? Perhaps the best thing is to have a view appear on import, then used the shared modelContext. In Xcode menu File/Add Package Dependencies... opens a popup. How is that done?
1
0
120
4d
Recursion in a SwiftUI Table
Using SwiftData for a MacOS app I have a working Table but I'd like to add recursion to the rows so instead of stopping at the first child level I can get to grandchildren, etc. Tried creating a separate func that calls itself but cannot get working syntax, possibly because this is happening inside a DisclosureTableRow or I just have bad syntax. Instead of calling TableRow(childAccount) I'd like to be able to call a recursive function which determines if each child is treated as a parent or not until there are no more grandchildren. Each Account class object has .parent: Account, .children: [Account], and .isExpanded:Bool (required by the DisclosureTableRow but not changed here). This is the working non-recursive code: ForEach(theAccounts.sorted(using: sortOrder)) { account in // Make this account bindable so can use .isExpanded directly @Bindable var account = account // Check if the account is not a child of any other account to avoid duplcates, if !theAssetAccounts.contains(where: { $0.children?.contains(account) ?? false }) { // If the account has children, display them in a DisclosureTableRow… if let children = account.children, !children.isEmpty { DisclosureTableRow(account, isExpanded: $account.isExpanded) { ForEach(children) { childAccount in TableRow(childAccount) } } } else { // …or if the account has no children, display it in a simple TableRow TableRow(account) } } } } First the singleton theMotherAccount is at the top level then we iterate over an array of other accounts, theAccounts, showing only those that are not themselves children. Any children are then surfaced as part of another DisclosureTableRow. I thought I could just create a recursive func to return either a DisclosureTableRow or a TableRow but have not been able to find acceptable syntax. This is what I thought ought to work: if let children = account.children, !children.isEmpty { return DisclosureTableRow(account, isExpanded: Bindable(account).isExpanded) { ForEach(children) { child in recursiveAccountRow(account: child) } } } else { return TableRow(account) } }
1
0
560
Feb ’24
.dropDestination on TableRow updated recently?
Using: @Model class Object: Observable, Transferable TableRow(object) .draggable(object) .dropDestination(for: Object.self) { _ in return } (with or without the "return") is the only .dropDestination syntax that compiles for me. Specifying the single return argument as (droppedItems:[Account]) is tolerated Using "return true" or expecting two returned items does not compile. I suspect the single returned item is the dropped items array, seems fair as "location" is not needed when using a TableRow. This is different behavior than all the docs and examples I've seen. My Object is Codable and Transferable. A row can be dragged and a destination row highlights on hover-with-payload, but on drop I get a spinning wheel even though I've not specified any action yet. The action closure is not entered, even a simple print() statement is not reached. I'd appreciate any thoughts on what might be the problem here. Debugger tips welcome, too. swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4) Target: arm64-apple-macosx14.0
1
0
349
Apr ’24
Sharing a Query in the Environment?
Using SwiftData I have one relatively short list of @Model class objects that are referenced in several views. I thought it would be handy to query once and share via the environment but my Table in other views does not update when data changes as it does when I repeat the Query in each view. Is this a bad idea or perhaps I implemented it improperly? @Observable class AllAccounts: ObservableObject { var accounts: [Account] = [] } struct ContentView: View { @Environment(\.modelContext) private var modelContext // an instance of the AllAccounts class, will save Query results to all.accounts @StateObject var all = AllAccounts() // one query for all accounts once in app, store in the environment` @Query private var allAccounts: [Account] .onAppear { all.accounts = allAccounts } .environment(all)
0
0
563
Mar ’24
SwiftData upsert duplicates problem or ?
Context: Importing JSON to have some data during development of SwiftData MacOS app. One object is repeated several times in the JSON and each copy is in the decoded data and does get inserted into the context and can be saved to the container, but then there are multiple copies of the same object with the same identifier in the database. When I qualify If the troublesome object's class with an @Attribute(.unique) identifier then the app crashes on .save. I was expecting a silent upsert. In this case there are three @Model classes. The model has a primary object with children objects and each child may have a third object type as a property and that third object may have a distinct third object listed as one of its own properties. It is this third object which appears several times in the file since it can be associated with many children. The insert code only specifies the primary object as I was expecting nested insertion of the children and the third object. Does this need to be handled differently? I'd like to only insert the first instance of the third object and keep the relationship intact. Should upsert work on .insert and might there be a technical problem?
1
0
737
Nov ’23