Search code examples
swiftcore-datansfetchrequest

Why is my fetchRequest returning nil?


My fetch request is returning nil from an entity that I think I've successfully put data into and after hours and hours of debugging, I haven't been able to figure it out. (Disclaimer: I've looked at the countless threads here on SO that talk about fetch requests and unwrapping options but every one I found is about how to deal with the unwrapping error. I'm asking for help figuring out why my fetch request isn't returning a record when I believe it should.)

In the view controller where I'm going to display the data, I have this in viewWillAppear:

class LiftLogTableViewController: UITableViewController {

    var managedObjectContext: NSManagedObjectContext!
    var liftEvents = [LiftEvent]() 

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

    let fetchRequest = NSFetchRequest(entityName: "LiftEvent")

    do {
      if let results = try managedObjectContext.executeFetchRequest(fetchRequest) as? [LiftEvent] {
        liftEvents = results  <---- nil error happening here

        }
    }  catch {
      fatalError("Error fetching data!")
    }
  }

But I believe there's a record in there because in AppDelegate.addData() I've done this:

    // create a lift event in LiftEvent
    let liftEvent = LiftEvent(entity: liftEventEntity, insertIntoManagedObjectContext: managedObjectContext)

    let dateStr = "05-27-2016"
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "MM-dd-yyyy"
    let date: NSDate = dateFormatter.dateFromString(dateStr)!

    liftEvent.date = date
    liftEvent.liftEventUid = 1
    liftEvent.liftUid = 1
    liftEvent.formulaUid = 1
    liftEvent.maxAmount = 250

    print("Added lift ID: \(liftEvent.liftEventUid) lift ID: \(liftEvent.liftUid) weight: \(liftEvent.maxAmount) formula: \(liftEvent.formulaUid) ")

    saveContext()

  }

func saveContext () {
    if managedObjectContext.hasChanges {
      do {
        try managedObjectContext.save()
      } catch {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        let nserror = error as NSError
        NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
        abort()
      }
    }
  }

I'm learning CoreData so at this point I have to assume there's something basic I'm just missing.

Thanks in advance.


Solution

  • Assuming you're using the standard Core Data template you need to assign a value to the managedObjectContext property in the LiftLogTableViewController class.

    For example in viewDidLoad

    override func viewDidLoad() {
      super.viewDidLoad()
      let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
      managedObjectContext = appDelegate.managedObjectContext
    }
    

    However the recommended way is to pass the context via the segue.