Update Core Data Object Order - Not Working

Update Core Data Object Order - Not Working

Well first of all, you might find it easier to create classes for each entity so that you don't have to work with objects vaguely typed to NSManagedObject or read and cast with valueForKey(_:). In the solution below, I've included code samples for that.

So to solve your order problem, there are two things you could do:

1) Add a property that defines the order of your Task entity. This can be a simple as an NSNumber called displayOrder. Your fetch request can then order the results according to that property. Then, when your table cells are re-arranged, iterate through the task list and update the displayOrder property of each task to reflect the order in which they are being displayed. Save your managed object context and the next time your fetch request loads, it will order them accordingly.

Sample Image

class Task: NSManagedObject {
@NSManaged var name: NSString
@NSManaged var desc: NSString
@NSManaged var displayOrder: NSNumber
}

let fetchRequest = NSFetchRequest()
let sortDescriptor = NSSortDescriptor(key: "displayOrder", ascending: true )
fetchRequest.sortDescriptors = [ sortDescriptor ]

2) Create a CoreData entity that represents a list with a to-many relationship that stores each task entity in an ordered set. Then, when you add tasks to the set, they will be remain saved in the order you've added them.

Sample Image

class TaskList: NSManagedObject {
@NSManaged var tasks: NSOrderedSet?
}

class Task: NSManagedObject {
@NSManaged var name: NSString
@NSManaged var desc: NSString
@NSManaged var parentList: TaskList?
}

Update to answer remaining questions:

I highly recommend you use your own custom classes instead of NSManagedObject, but until you figure that part out here's what you can do to your code as is.

To update display order after rearranging or deleting:

func updateDisplayOrder() {
for i in 0..<todayTaskList.count {
let task = todayTaskList[i]
task.setValue( i, forKey: "displayOrder" )
}
}

To append a new task:

func addTask( task: NSManagedObject, displayOrder: Int ) {
todayTaskList.insert( task, atIndex: displayOrder )
updateDisplayOrder()
}

SwiftUI List not updating when core data property is updated in other view

NSManagedObject is a reference type so when you change its properties your documents is not changed, so state does not refresh view.

Here is a possible approach to force-refresh List when you comes back

  1. add new state
@State var documents: [ScanDocument] = []
@State private var refreshID = UUID() // can be actually anything, but unique

  1. make List identified by it
List(documents, id: \.id) { item in
ZStack {
DocumentCell(document: item)
}
}.id(refreshID) // << here

  1. change refreshID when come back so forcing List rebuild
NavigationLink(destination: RenameDocumentView(document: documents[selectedDocumentIndex!])
.onDisappear(perform: {self.refreshID = UUID()}),
isActive: $pushActive) {
Text("")
}.hidden()

Alternate: Possible alternate is to make DocumentCell observe document, but code is not provided so it is not clear what's inside. Anyway you can try

struct DocumentCell: View {
@ObservedObject document: ScanDocument

...
}

Not update Table after saving or updating Core data - Swift

I removed privateManagedObjectContext and just use from mainManagedObjectContext, good work now. And removed Z_PK from primary status.

Updated core data values not Reflecting in SwiftUI List

Call

getTaxCodes()

When you want to see an update.

No part of your code is observing the persistent store. Your list doesn’t know when to get the new values

You completely disconnect from CoreData with the View Model and struct. If you are doing this for abstraction and not unintentionally it’s fine but you have to somehow listen to the store so you can recreate everything.

Using something in the View like onChange may or may not provide updates when needed. The store can change from many different directions that your abstraction layer will be unaware of.

This may offer you an alternative for listening.

If this is an unintentional pattern use the CoreData object directly by wrapping it with an

@ObservedObject

That way you can make changes and see them right away.

The link above also has a more direct setup for CoreData and has a simple

CoreDataPersistence

Object that does all the heavy lifting for any object.

Objects not sorted after creation Core Data SwiftUI

The problem seems that it is just not assigned in the provided code, because naming attribute by id means noting in CoreData (and by default remains 0), so at least with added below it is updated & sorted properly (in testing model id is Int32, but it is not important)

for i in 1...5 {
let language = ProgrammingLanguage(context: self.managedObjectContext)
language.id = Int32(i) // << here !!
language.name = "\(i) SwiftUI"

Tested with Xcode 11.4 / iOS 13.4

How to update objects in core data?

If you want to update quantity of the current object ff try with these lines.

        let ff: Cart!
let indexPath = self.tableView?.indexPathForSelectedRow
ff = self.cart[indexPath!.row]
let app = UIApplication.sharedApplication().delegate as! AppDelegate
let context = app.managedObjectContext
ff.setValue(Int(txt.text!), forKey: "quantity")
do{
try context.save()
self.viewDidLoad() // why you call this line here ?
print(cartt.longg)
print(cartt.delivery)
print("saved")
}catch{
print("could not save")
}

Why did you call self.viewDidLoad()?

On your next code, you was creating a new item rather than just updating the current one.

SwiftUI update view on core data object change

Try to observe Asset (cause NSManagedObject is-a ObservableObject)

struct AssetRowView: View {
@ObservedObject var asset: Asset // << here !!

var body: some View {
HStack {
Text(asset.name)
Text(asset.assetDescription)
}
}
}

if that will not be enough, also might be needed to update Done button action as

}, trailing: Button("Done") {
self.asset.objectWillChange.send() // << here !!
self.asset.name = self.name
self.asset.assetDescription = self.description
try? self.moc.save()

// better do this at the end of activity
self.presentationMode.wrappedValue.dismiss()
}


Related Topics



Leave a reply



Submit