Saturday 23 February 2019

Core Data sometimes loses data

We are running an App through Citrix Secure Hub, it seems that sometimes there is a rollback with loosing some Data in CoreData.

As i understand, CoreData is having something like an working copy of all the objects, and sometimes its tries to persist that on the filesystem.

Well tried to simulate the behavior but without any success, we could not find out any data loss or rollbacked data in our test environment.

So is there a way to force iOS to write the current "working copy" on the disk to prevent any data loss when using too much memory (and maybe crash)? We call our save function after

As we already found out:

We were NOT using:

func applicationWillResignActive(_ application: UIApplication) {
      print("applicationWillResignActive")
}

to save the context, could this be a problem (we are already saving the context after every created object)

At the Moment we dont really handle problems when the context could not be saved, are there any recommendations how to handle that in a productive environment? And is it a good thing to maybe crash to app to prevent the user from struggeling with data loss?

Edit: this is the used Core Data Handler:

import Foundation
import CoreData

let context = CoreDataManager.shared.managedObjectContext

func saveContext(_ completion: (() -> Void)? = nil) {

     CoreDataManager.shared.save(completion)
}

func saveContextSync() {

     CoreDataManager.shared.saveSync()
}

class CoreDataManager: NSObject {

    static let shared = CoreDataManager()

    lazy var managedObjectContext: NSManagedObjectContext = {

    var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)

    managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator

    return managedObjectContext
}()

And our save functionality:

@objc func save(_ completion: (() -> Void)?) {

    saveAsync(completion)
}

func saveAsync(_ completion: (() -> Void)?) {

    func save() {

        context.perform {
            do { try context.save() }
            catch {
              // HERE WE NEED TO HANDLE IT FOR A PRODUCTIVE ENVIRONMENT
            }

            completion?()
        }
    }

    if Thread.isMainThread {
        save()
    } else {
        DispatchQueue.main.async {
            save()
        }
    }

}

func saveSync() {

    func save() {
        context.performAndWait {
            do { try context.save() }
            catch { print(error)
                // TRY TO REPRODUCE MEMORY LOSS APP TO SEE WHAT HAPPENS
                abort()
            }
        }
    }

    if Thread.isMainThread {
        save()
    } else {
        DispatchQueue.main.sync {
            save()
        }
    }
}



from Core Data sometimes loses data

No comments:

Post a Comment