'CoreData fetch request returns an object with nil properties when changing app state

I have some code that helps with managing current Managed Object Context

var currentContext: NSManagedObjectContext {
    if Thread.isMainThread {
        return mainContext
    } else {
        return backgroundContext
    }
}

var mainContext: NSManagedObjectContext {
    return persistentContainer.viewContext
}

lazy var backgroundContext: NSManagedObjectContext = {
    let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
    context.parent = mainContext
    
    return context
}()

Fetch function

public func entities(_ fetchOptions: FetchOptions) -> [T] {
    let fetchRequest = NSFetchRequest<T>(entityName: T.entityName)
    
    switch fetchOptions {
    case let .filtered(predicate):
        fetchRequest.predicate = predicate
    case let .sorted(sortDescriptors):
        fetchRequest.sortDescriptors = sortDescriptors
    case let .filteredAndSorted(predicate, sortDescriptors):
        fetchRequest.predicate = predicate
        fetchRequest.sortDescriptors = sortDescriptors
    case .all:
        fetchRequest.sortDescriptors = []
    }
    
    fetchRequest.returnsObjectsAsFaults = false
    
    let context = CoreDataContextProvider.provider.currentContext
    
    return (try? context.fetch(fetchRequest)) ?? []
}

Let's say I have a request that gets some data from the server and writes it to the CoreData. When i use the app in the foreground, everything works well, but when i enter the background, for example, switch into another app, and then go back, fetch request from current context for a particular entity returns something like

SomeEntity {
   var property1 = 0;
   var property2 = nil;
   var property3 = nil;
   ... etc
}

Data is correct in the background context, and I get this behaviour exactly after switching back to the main one.

I've tried saving current context on UIApplication.didEnterBackgroundNotification and UIApplication.willEnterForegroundNotification, so that changes got pushed anyway, but it seems to do no favour.

Also, I've tried to merge main and background context on NSManagedObject.didSaveObjectsNotification, and got same results, but I don't rule out that I did something wrong here.

When I use main context only, everything seems to be working fine, but I get serious UI freezes once in a while.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source