Post

Replies

Boosts

Views

Activity

Reply to Xcode 12 beta 6 Core Data generated source yields compilation errors
hi, not sure it's a bug, as such. (it's a feature!) if you had an NSManagedObject in Xcode 11 with an id attribute, to make it Identifiable you would likely add an extension to the class in your own code to say that it conforms to Identifiable (without doing anything special). Xcode 12 seems to sense that you have an id field (that's Hashable) as an attribute and adds its own extension to the class to say that it's Identifiable in its generated file. just remove your own addition of conformance to Identifiable. hope that helps, DMG
Topic: Programming Languages SubTopic: Swift Tags:
Sep ’20
Reply to Navigate back after saving in Swift UI
hi, since you tagged Core Data, i'll assume you are seeing a detail view of a Core Data object. the situation depends on whether this is a live edit or not. if this is a live edit, any change you make in the Detail view to the fields of the object (which is already an ObservableObject, and you would indicate that it be an @ObservedObject in your code) is done immediately; using the Back button works as is. if this is not a live edit, one might off-load all the values to be edited to @State variables when the view appears; those variables become the editable items; and when the user taps a Save button, the @State variables are copied back to the Core Data object to commit the edit. if it's the latter situation, one possibility is to hide the Back button; replace it with a Cancel button (so any edits are ignored), and add a Save button. you could do something like this: // define this in your Detail view @Environment(\.presentationMode) var presentationMode // and you have some Core Data object for this View var myObject: MyCoreDataObject // and lots of View code, with the following modifiers attached .navigationBarBackButtonHidden(true) .navigationBarItems( leading: Button(action : { self.presentationMode.wrappedValue.dismiss() }){ Text("Cancel") }, trailing: Button(action : { self.commitDataEntry() }){ Text("Save") }) .onAppear(perform: loadStateVariables) the loadStateVariables function would copy values from the core data object to the @State variables, and the commitDataEntry() function would copy values from the @State variables back to the object and then dismiss with the same presentationMode.wrappedValue.dismiss() call. i'll leave it to the UI police about whether this is the best of policies. hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’20
Reply to Xcode 12: print() not printing to debug area
hi, (perhaps not your issue, but still, FWIW): Xcode 12 has a habit of opening projects with the Debug View at the bottom of the Xcode window showing only the Variables view, but not the Console window. you may need to click on the "Show the Console" button at the bottom, right of the Debug area, or follow the menu choices View --> Debug Area --> Activate Console. hope that helps, DMG
Sep ’20
Reply to Deleting in a ForEach with .filter
hi, the easiest method (assuming that you only use .onDelete with completed items, where $0.completed == false): since your delete function is given offsets into the "Open" list, start by getting that list with the same filter process, then modify your removal code based on pulling out items from the filtered list by the indices you have. something like this should work: func delete(at offsets: IndexSet) { 	let openEvents = viewModel.eventsList.filter { $0.completed == false } 	viewModel.removeEvents( offsets.map({ openEvents[$0] }) ) } where the removeEvents function on your viewModel removes all events in the given list: func removeEvents( events: [Event] ) { 	eventList.removeAll(where: { events.contains($0) }) } of course, you might not actually be removing these; perhaps you are just be setting the completed value to true. hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’20
Reply to Is it possible to delete an item from Coredata using onTapGesture?
hi, the .onDelete modifier is usually something you add to a ForEach, as in List { 	ForEach(items) { item in 		Text(item.name) 	} 		.onDelete(perform: yourDeleteFunction) } the .onTapGesture is something you would add to a view associated with an item in the list, within the scope of the ForEach: List { 	ForEach(items) { item in 		Text(item.name) 			.onTapGesture({ doSomething(to: item) }) // doSomething could certainly delete this item 	} } (i think that's right and) hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’20
Reply to List Core Data Entity Relationships
hi, in response to @toqix, i don't know exactly the definition of your entities, but the general principle is that if entity A has a one-to-many relationship with entity B (that is, each A can have many Bs, but each B is associated with only one A), then changing an attribute's value on a B does not trigger a SwiftUI view update on a view that is driven by a @FetchRequest or @ObservedObject for A -- because no attribute of A has been changed. the solution is usually that if you change an attribute's value on a B, then also determine its associated A, possibly some a = B.referenceBackToA (depending on how you named the relationship in B), and call a?.objectWillChange.send(). hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’20
Reply to Passing NSManagedObject SwiftUI
hi, i am assuming that you are describing this problem: you tap the Add button inTaskItemsView the addTask() function does indeed add a new Task to the list (var list: TaskList) the TaskItemsView does not update if that's the case, in TaskItemsView, you should do two things: define the list variable as @ObservedObject var list: TaskList. this makes the TaskItemsView responsive to changes in Core Data attributes of the list. after line 43 (list.addToItems(newTask)) add list.objectWillChange.send(). adding a new TaskItem to the list's NSSet of TaskItems is not seen as a change to a list attribute (its reference to the NSSet), so you need to signal a change to the list yourself. hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Dec ’20
Reply to SwiftUI update of deleted CoreData entities from different Tab
hi, your question made me realize i had something like this situation occurring as a very remote possibility in one of my projects. my solution (which works, as far as i have tested) is: when a detail view is initialized, record the id of the object you display (you do have an id: UUID? attribute on the object, yes?). with every .onAppear() of the DetailView, use a Core Data fetch to see whether you still have a CD object with that id. if no such object exists, then just dismiss the detail view right away. hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’21
Reply to SwiftUI update of deleted CoreData entities from different Tab
hi Bernhard, you could take a look at my ShoppingList14 project over on GitHub - https://www.github.com/delawaremathguy/ShoppingList14, where i (sort of) solve the problem of having two edit views open on the same CD object in two different tabs and "delete" the object in one of those views. i make sure that the second one goes away before it can be seen when returning to the other tab. you will find my comments about this situation in the file AddOrModifyItemView.swift. i can't say i know enough about using isFault, since it will be true when the object is deleted, but isDeleted will be false. on the other item you mentioned, about changing a property of a CD object Y that's associated via some relationship with a CD object X, no change has been made to the attributes of X (only to the underlying NSSet or NSOrderedSet for the relationship of X). so X never sees a change to one of the properties in Y. you can work around this; when a change is made to Y, find any and all X to which it is related and call X.objectWillChange.send(). you will find that i do this in ShoppingList14, and i have included some lengthy comments about this strategy, mostly for the case where X has computed properties that are based on the associated Ys (see Item+Extensions.swift and Location+Extensions.swift). hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’21
Reply to View with @FetchRequest doesn't update when items added/removed from another device
hi, did you set NSPersistentHistoryTrackingKey and NSPersistentStoreRemoteChangeNotificationPostOptionKey, along with automaticallyMergesChangesFromParent and the mergePolicy? i use this code. guard let persistentStoreDescriptions = container.persistentStoreDescriptions.first else { fatalError("\(#function): Failed to retrieve a persistent store description.") } persistentStoreDescriptions.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) persistentStoreDescriptions.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) container.loadPersistentStores(completionHandler: { (storeDescription, error) in ... }) container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy there's also a recent article by Becky Hansmeyer (h ttps://beckyhansmeyer.com) that may be helpful. hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Apr ’21
Reply to Initializing State from another object
hi, instead of writing from = filter.criteria.from ?? "" to = filter.criteria.to ?? "" you should be writing _from = State(initialValue: filter.criteria.from ?? "") _to = State(initialValue: filter.criteria.to ?? "") this is a syntactic issue with @State: you need to initialize the property wrapper, not its value. hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Apr ’21
Reply to CoreData not updating Property
hi, we do not see the definition of category in this view, but i am hoping that it would ideally be @ObservedObject var category: Category // not an optional, so reference category.CitemsArray in the ForEach you should know that changing a property of one of the category's associated items is not seen as a change to the category object itself, and it will not trigger a visual update of the view. when you do item.done.toggle() in the .onTapGesture, consider registering an explicit change on the category object with category.objectWillChange.send() hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
May ’21
Reply to CloudKit and CoreData synchronization
hi, it may be as simple as not turning on history tracking. in my code, i usually have these lines right after creating the NSPersistentCloudKitContainer: // (1) Enable history tracking. this seems to be important when you have more than one persistent // store in your app (e.g., when using the cloud) and you want to do any sort of cross-store // syncing. See WWDC 2019 Session 209, "Making Apps with Core Data." guard let persistentStoreDescription = container.persistentStoreDescriptions.first else { fatalError("\(#function): Failed to retrieve a persistent store description.") } persistentStoreDescription .setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) persistentStoreDescription .setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’21