UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Items aren't updated in List after updating them in CoreData

Forums > SwiftUI

I have List of items and fetch them from CoreData

@FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
private var items: FetchedResults<Item>

var body: some View {
            List {
                ForEach(items) { item in
                    Text("Item at \(item.timestamp!, formatter: itemFormatter)")
                }               
            }
}

I try to upate all items but UI shows old values. Item entity has new values in sqlite.

let request = NSBatchUpdateRequest(entity: Item.entity())
request.propertiesToUpdate = ["timestamp": Date()]
do {
    try viewContext.execute(request)
} catch {
    let nsError = error as NSError
    fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}

3      

Core Data batch updates do not update the in-memory objects. You have to manually refresh afterwards.

Batch operations bypass the normal Core Data operations and operate directly on the underlying SQLite database (or whatever is backing your persistent store). They do this for benefits of speed but it means they also don't trigger all the stuff you get using normal fetch requests.

You need to do something like shown in Apple's Core Data Batch Programming Guide: Implementing Batch Updates - Updating Your Application After Execution

4      

@roosterboy Thank you for the detailed explaination. I changed my code like this.

do {
    let request = NSBatchUpdateRequest(entity: Item.entity())
    request.resultType = .updatedObjectIDsResultType
    request.propertiesToUpdate = ["timestamp": Date()]

    let result = try viewContext.execute(request) as? NSBatchUpdateResult
    let objectIDArray = result?.result as? [NSManagedObjectID]
    let changes = [NSUpdatedObjectsKey: objectIDArray]
    NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [viewContext])
} catch {
    let nsError = error as NSError
    fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.