Core Data NSFetchRequest Optional error?

Hello!


Last week I bought myself a course on udemy.com regarding the use of Core Data, however - as I followed the tutorial and downloaded the project-file it all went well. When I created a new project, and pretty much followed the tutorial once more. This time, I get an error each time I want to display sorted data (printing). This is my code in ViewDidLoad:


var context: NSManagedObjectContext!;

let predicate = NSPredicate(format: "name == '\(selectedName)'")
        let request = NSFetchRequest(entityName: "Profile")
        request.predicate = predicate
    
    
        let  result = (try! self.context!.executeFetchRequest(request)) as! [Profile]
    
        dtm = try! self.context!.executeFetchRequest(request) as! [Profile]
        for prof in result {
            /
            print(prof.name!)
        }

This is however, the error I am getting:

fatal error: unexpectedly found nil while unwrapping an Optional value


It may be worth mentioning that my entity is called Profile, but I am not sure if I have the correct settings or not. I have tried everything I know about, and I really hope you can help me with this. Thank you.

Accepted Reply

You will need something like this:


let appDelegate: AppDelegate = {
        return UIApplication.sharedApplication().delegate as! AppDelegate
    }()

var context = appDelegate.managedObjectContext

Replies

I see six ! in your code. You have the debugger running on your computer, which line of code is the one where you're optional unwrapping is failing?


This may be an excellent opportunity for you to learn all of the debugging features that Xcode provides you.

The error occurs on line 8. This exact line: let result = (try! self.context!.executeFetchRequest(request)) as! [Profile]


If I remove this line however, the error seem to occur here as well: dtm = try! self.context!.executeFetchRequest(request) as! [DebtToMe]

The error occurs on line 8. This exact line: let result = (try! self.context!.executeFetchRequest(request)) as! [Profile]

In that single line, you have so many opportunities to get runtime errors:

[1] context may be nil

[2] executeFetchRequest may fail with error

[3] the result of executeFetchRequest cannot be converted to [Profile]

Replace the line with the following code snippet and find which actually is causing the crash:

        assert(context != nil, "context is nil")
        let fetchResult: [AnyObject]
        do {
            fetchResult = try self.context!.executeFetchRequest(request)
        } catch let error as NSError {
            fatalError("executeFetchRequest failed with:\(error)")      
        }
        guard let result = fetchResult as? [Profile] else {
            fatalError("fetchResult cannot be converted to [Profile]")
        }


By the way, if your bought course suggested to use so many `!`s, you would have chosen a bad one.

Thank you for your help. I get an error on the assert(context != nil, "context is nil") - telling me that context is in fact nil. However, I don't know what the problem is, as the Entity name is the same, and the attribute "name" do also exist. It also has a value? What may this be?


Regarding the course; No, this was something I put in - while I was trying my best to solve my problems.

You need to initialize the context, if you haven't done so already. If you checked the CoreData checkmark when you created your project, you probably have one already initialized in your app delegate.

I did check 'Use Core Data' in my creation of the project, yes. I still don't see anything wrong with my code, as I followed a tutorial. Could you tell me how I would 'Initialize' this contezt properly?

If you have created a project with `Use Core Data` checked, you can find this sort of code in AppDelegate.

    lazy var managedObjectContext: NSManagedObjectContext = {
        //...
        let coordinator = self.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }()

You need to initialize an NSManagedObjectContext this way. So, how have you initialized your `context`?

Yes, I found this code in my AppDelegate:


lazy var managedObjectContext: NSManagedObjectContext = {
        /
        let coordinator = self.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }()

Error is still not fixed, by the way.

Now you need to use this context. In your code snippet, you declared another one and attempt to use that.

Sorry for this misunderstanding, but I don't seem to understand what you mean. Could you please elaborate? How would I do this? I am kind of new to this. Again, sorry. Isn't it enough with just this:

var context: NSManagedObjectContext!; ?

You will need something like this:


let appDelegate: AppDelegate = {
        return UIApplication.sharedApplication().delegate as! AppDelegate
    }()

var context = appDelegate.managedObjectContext

Thank you so much! Helped me a lot!