0

I have been unable to find any information myself that was helpful to this topic, and I am somewhat new and self taught so apologies for any ignorance. I am making a contacts style app that allows you to record visits made with a specific person. I am using Core Data to store the data and have a one to many relationship linking the Person entity to the Visit entity.

As I segue from the main contacts list by selecting a specific person I am passing that nsmanagedobject of Person to the new view controller and using that as my predicate when fetching which visits I've made on the person.

The issue arises from state restoration at this point. I want to be able to return to this person's page (and a few other instances throughout the app, but this one example covers the issue) but because I was passing the Person object through the segue, that object is now nil, which causes my app to crash twice, then it launches to the main screen, appearing to clear and restoration data.

No matter what I try to store in encoderestorablestate:with, press home, then stop the app in xcode then relaunch in xcode, the decoderestorablestate func is never called and crashes with person being nil before that.

Below is my fetchedresultscontroller and the crash happens on the predicate line saying self.person is nil

 lazy var fetchedResultsController: NSFetchedResultsController<Visit> = {

    // Initialize Fetch Request
    let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest(entityName: "Visit")
    // Add Sort Descriptors
    let predicate = NSPredicate(format: "person == %@", self.person!)
    fetchRequest.predicate = predicate

    let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
    fetchRequest.sortDescriptors = [sortDescriptor]

    // Initialize Fetched Results Controller
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    // Configure Fetched Results Controller
    fetchedResultsController.delegate = self

    return fetchedResultsController as! NSFetchedResultsController<Visit>

}()

i will restate this all works perfectly and as expected when using the app from the top, it only crashes when attempting to restore state.

I have made many different attempts at what to put in encoderestorablestate with but nothing has stopped the crash. This seems like something that would come up a lot, but my lack of finding any information has me confused.

Thank you for your time.

1 Answers1

0

You have not given sufficient information to track down the issue, but here's a general way of looking at the problem. Consider the issue in three parts:

  • You have a restoration class that implements viewController(withRestorationIdentifierPath:coder:). This is an opportunity to configure the view controller you're supplying.

  • The view controller is sent decodeRestorableState(with:). This is another opportunity to configure the view controller. Note that this comes after viewDidLoad.

  • The view controller is sent applicationFinishedRestoringState. This is your final opportunity to configure the view controller.

Now let's think about how you're going to update the interface on this view controller. The timing is tricky, because you don't know what the timing will be. In particular, you may have code in viewDidLoad that assumes that all properties have been set, and configures the interface accordingly. But in this situation, they probably have not been set.

Thus, for state restoration to work, you need to rewrite your viewDidLoad code to make no assumptions about whether properties have been set.

In your case, that would be self.person. In viewDidLoad, you need to check self.person and, if it is nil, don't try to make your fetched results controller yet. Then applicationFinishedRestoringState comes along, and now you have probably configured self.person (in your decodeRestorableState), and you can update the interface through your fetched results controller.

matt
  • 447,615
  • 74
  • 748
  • 977