1

It says Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

(my code)

func getData()  {

   let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Entity")
    request.returnsObjectsAsFaults = false
    do {
        let result = try? context.fetch(request)

        for data in result as! [NSManagedObject] {

            FacialViewControllerA = data.value(forKey: "titleA") as! String


    }

enter image description here

Sulthan
  • 128,090
  • 22
  • 218
  • 270
Myz
  • 71
  • 1
  • 9
  • 5
    Possible duplicate of: [What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – TylerP Apr 25 '20 at 19:22
  • 1
    your result is nil and you are trying to force wrap to [NSManagedObject]. That's why this error is coming. – Mohit Kumar Apr 25 '20 at 19:24
  • can u help me to fix it. – Myz Apr 25 '20 at 19:38

2 Answers2

2

Please refer to Tyler's comment so you learn more about optionals. Also, avoid the usage of ! which is used to force unwrap objects.

In your case, the crash could be happening due to two reasons:

  • Either the object you are trying to unwrap is not an array [NSManagedObject]

  • Or the fetchRequest returned 0 objects or nil value

To avoid the crash you should opt for optional unwrapping which is the safest way of unwrapping an object. You can either a guard-let or If-let statement Please refer to the code below:

Using guard-let:

guard let unwrappedResult = result as? [NSManagedObject] else {
        print("unwrap of result failed")
        return
 }
 for data in unwrappedResult {
     //perform your logic
 }

Using if-let:

if let unwrappedResult = result as? [NSManagedObject] {
   for data in unwrappedResult {
       //perform your logic
   }
}
Vikram Parimi
  • 777
  • 6
  • 29
1

You've misunderstood what the do-try-catch block does.

When you put the ? after try you are preventing the catch from getting hit. So if try fails, it is setting result to nil. Then you are force casting nil to [NSManagedObject].

You have two options:

  • Remove the ? after try
  • Like Vikram mentioned, don't force cast result, use as? [NSManagedObject]

1)

do {
    let result = try context.fetch(request)
    for data in result as! [NSManagedObject] {
        FacialViewControllerA = data.value(forKey: "titleA") as! String
    }
} catch {
    print("There was an error: \(error)")
}

2)

if let result = try? context.fetch(request) as? [NSManagedObject] {
    for data in result  {
        FacialViewControllerA = data.value(forKey: "titleA") as! String
    }
}
Wyetro
  • 8,439
  • 9
  • 46
  • 64