libc++abi.dylib: terminating with uncaught exception of type NSException; How to catch exceptions

511 Views Asked by At

I have a simple piece of code, for which I am trying to catch exceptions.

do {
        let result = activity_record.setValue(name, forKeyPath: "key_TRANSACTION_NAMEs")
    }
    catch {
        print("Could not save record error")
        // Display an error that record could not be saved
        let alert = UIAlertController(title: "Error", message: "Could not save record",  preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }

When I run this code, the application crashes with the error code -

libc++abi.dylib: terminating with uncaught exception of type NSException

I am not able to catch the error and elegantly handle it in the code. Can you please recommend the best way to solve this? I am using CoreData, IOS target 9.3 Swift 3, XCode 8. The "key_TRANSACTION_NAMEs" is purposefully entered wrong to test the code (to catch exceptions).

I am using the following in AppDelegate to get the managedcontext (databaseContext)

// MARK: - utility routines lazy var applicationDocumentsDirectory: URL = { let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) return urls[urls.count-1] }()

// MARK: - Core Data stack (generic)
lazy var managedObjectModel: NSManagedObjectModel = {

    // Changed name to "ChildOpenBarn" and withExtention to "momd"
    let modelURL = Bundle.main.url(forResource: "ChildOpenBarn", withExtension: "momd")
    return NSManagedObjectModel(contentsOf: modelURL!)!
}()

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    // Changed name to "ChildOpenBarn" and withExtention to "sqllite"

    let url = self.applicationDocumentsDirectory.appendingPathComponent("ChildOpenBarn").appendingPathExtension("sqllite")

    do {
        try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
    } catch {
        let dict : [String : Any] = [NSLocalizedDescriptionKey        : "Failed to initialize the application's saved data" as NSString,
                                     NSLocalizedFailureReasonErrorKey : "There was an error creating or loading the application's saved data." as NSString,
                                     NSUnderlyingErrorKey             : error as NSError]

        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        fatalError("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
    }

    return coordinator
}()

// MARK: - Core Data stack (iOS 9)
@available(iOS 9.0, *)
lazy var managedObjectContext: NSManagedObjectContext = {
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
    return managedObjectContext
}()

// MARK: - Core Data stack (iOS 10)
@available(iOS 10.0, *)
lazy var persistentContainer: NSPersistentContainer = {
    //Changed name to "ChildOpenBarn"
    let container = NSPersistentContainer(name: "ChildOpenBarn")
    container.loadPersistentStores(completionHandler: {
        (storeDescription, error) in
        if let error = error as NSError?
        {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    }
    )

    return container
}()

// MARK: - Core Data context
lazy var databaseContext : NSManagedObjectContext = {
    if #available(iOS 10.0, *) {
        return self.persistentContainer.viewContext
    } else {
        return self.managedObjectContext
    }
}()

Taking motivation from Lajos answer; What should I return (NSString) for this function

extension NSObject {
    func setValue(anObserver: NSObject!,
              forKeyPath keyPath: String!,
              options: NSKeyValueObservingOptions,
              context: UnsafeMutablePointer<Void>) -> NSString! {
    return
    }
}
0

There are 0 best solutions below