Jim Jim - 6 months ago 11
Swift Question

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.

Answer

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.