-1

Got a fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value. I can't find the reason for the error - let results = try context.fetch(fetchRequest).

This is the block where I get the error:

override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        
        let userName = "Max"
        let fetchRequest: NSFetchRequest<User> = User.fetchRequest() //хотим получать данные по юзеру
        fetchRequest.predicate = NSPredicate(format: "name == %@", userName) //пишем предикат для имени
        
        do {
            let results = try context.fetch(fetchRequest)
            if results.isEmpty {
                user = User(context: context) //если нет юзера Макс, то создаем его и помещаем в контекст
                user.name = userName //создали и присвоили имя
                try context.save() //сохраняем
            } else {
                user = results.first //если есть юзер в базе, то сразу присваиваем его в var user: User!
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }
    }
}

And this is all ViewController code:

import UIKit
import CoreData

class ViewController: UIViewController {
    
    @IBOutlet var tableView: UITableView!
    
    var context: NSManagedObjectContext!
    
    var user: User!
    
    lazy var dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .short
        formatter.timeStyle = .short
        return formatter
    }()
    
    @IBAction func addButtonPressed(_ sender: UIBarButtonItem) {

        let meal = Meal(context: context) //создали объект мил
        meal.date = Date() //присвоили ему текущую дату
        //создаем копию приемов пищи у юзера
        let meals = user.meals?.mutableCopy() as? NSMutableOrderedSet //массив
        meals?.add(meal) //добавляем новый примем пищи meals
        user.meals = meals  //присвоили юзеру новый массив
        
        do {
            try context.save()
            tableView.reloadData()
        } catch let error as NSError {
            print(error.localizedDescription)
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        
        let userName = "Max"
        let fetchRequest: NSFetchRequest<User> = User.fetchRequest() //хотим получать данные по юзеру
        fetchRequest.predicate = NSPredicate(format: "name == %@", userName) //пишем предикат для имени
        
        do {
            let results = try context.fetch(fetchRequest)
            if results.isEmpty {
                user = User(context: context) //если нет юзера Макс, то создаем его и помещаем в контекст
                user.name = userName //создали и присвоили имя
                try context.save() //сохраняем
            } else {
                user = results.first //если есть юзер в базе, то сразу присваиваем его в var user: User!
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }
    }
}

// MARK: - UITableViewDataSource

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "My happy meal time"
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return user.meals?.count ?? 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as UITableViewCell
        
        //нужно получить конкретны�� прием пищи и поместить его в конкретную строку
        guard let meal = user.meals?[indexPath.row] as? Meal,
              let mealDate = meal.date
        else { return cell } //если не получилось просто вернули пустую ячейку
        
        cell.textLabel!.text = dateFormatter.string(from: mealDate)
        return cell
    }
}
3
  • 1
    var context: NSManagedObjectContext! Where is set context? It's declared, but I don't see where it's set. I guess it's nil. And since you declared it var context: NSManagedObjectContext! with a question mark, it's says: "Don't worry, it can be nil, else crash with error Unexpectedly found nil while implicitly unwrapping an Optional value if it's used and is nil".
    – Larme
    Commented May 30 at 9:38
  • Maybe learn how to use the debugger? Commented May 30 at 10:59
  • @Larme thanks, I'll go figure it out
    – deshollow
    Commented May 30 at 12:13

1 Answer 1

-1

Ok, the error turned out to be prosaic. Wrong name in:

let container = NSPersistentContainer(name: "MaelTime") 

instead of MealTime:

class CoreDataStack {
    
    lazy var persistentContainer: NSPersistentContainer = {
        /*
         The persistent container for the application. This implementation
         creates and returns a container, having loaded the store for the
         application to it. This property is optional since there are legitimate
         error conditions that could cause the creation of the store to fail.
         */
        let container = NSPersistentContainer(name: "MaelTime")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() 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.
                
                /*
                 Typical reasons for an error here include:
                 * The parent directory does not exist, cannot be created, or disallows writing.
                 * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                 * The device is out of space.
                 * The store could not be migrated to the current model version.
                 Check the error message to determine what the actual problem was.
                 */
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()
    
    func saveContext () {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() 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
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

Not the answer you're looking for? Browse other questions tagged or ask your own question.