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
}
}