libc++abi.dylib: terminar con excepción no capturada de tipo NSException en la aplicación de iam edificio
mientras que la construcción de la aplicación que estoy recibiendo un mensaje de error al hacer clic
Subproceso 1: señal de SIGABRT en aplicación delegado *** Terminación de la aplicación debido a uncaught exception 'NSUnknownKeyException', la razón: '[ setValue:forUndefinedKey:]: esta clase no es el valor de la clave codificación compatible con la tecla de mainContainer.'
cuando yo hacer clic sobre el icono lanza un hilo
import UIKit
import CoreData
class ActionPlanViewController: UIViewController, addMedDelegate, addRelieverDelegate, addInfoDelegate {
//for storing medicine
var medicineList: [Medicine]?
var selectedActionPlan: ActionPlan?
var oldMed: Medicine?
var typeOfMedicineSelected: String = ""
var selectedPreventer: Medicine?
//references to view elements
//header
@IBOutlet weak var headerStat: UILabel!
@IBOutlet weak var headerImg: UIImageView!
//preventer
@IBOutlet weak var preventerName: UILabel!
@IBOutlet weak var preventerDescription: UILabel!
@IBOutlet weak var buttonText: UIButton!
@IBOutlet weak var preventerPic: UIImageView!
@IBOutlet weak var relieverName: UILabel!
@IBOutlet weak var relieverDescription: UILabel!
@IBOutlet weak var rButtonText: UIButton!
@IBOutlet weak var relieverPic: UIImageView!
//information and spencer
@IBOutlet weak var infoLabel: UILabel!
@IBOutlet weak var ifUseSpencer: UISegmentedControl!
//for changing and saving spacer value
@IBAction func saveSpacerValue(_ sender: Any) {
if ifUseSpencer.selectedSegmentIndex == 0{
//if user selects yes
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "ActionPlan")
fetchRequest.predicate = NSPredicate(format: "type = %@", (selectedActionPlan?.type)!)
do{
let test = try managedObjectContext?.fetch(fetchRequest)
let objectUpdate = test![0] as! NSManagedObject
objectUpdate.setValue(true, forKey: "useSpencer")
do{
try managedObjectContext?.save()
}
catch{
print(error)
}
}
catch{
print(error)
}
}
if ifUseSpencer.selectedSegmentIndex == 1{
//if user selects yes
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "ActionPlan")
fetchRequest.predicate = NSPredicate(format: "type = %@", (selectedActionPlan?.type)!)
do{
let test = try managedObjectContext?.fetch(fetchRequest)
let objectUpdate = test![0] as! NSManagedObject
objectUpdate.setValue(false, forKey: "useSpencer")
do{
try managedObjectContext?.save()
}
catch{
print(error)
}
}
catch{
print(error)
}
}
}
//for accessing coredata
var managedObjectContext: NSManagedObjectContext?
//declaring helper object for manipulating plist
var plistHelper = PListHelper()
//coredata initialization
required init?(coder aDecoder: NSCoder) {
let appDelegate = UIApplication.shared.delegate as? AppDelegate
managedObjectContext = (appDelegate?.persistentContainer.viewContext)!
super.init(coder: aDecoder)!
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//setting user preferences
headerStat.text = "When \((plistHelper.readPlist(namePlist: "contacts", key: "Child")["First Name"]!)!) is \((selectedActionPlan?.type)!)"
if selectedActionPlan?.type == "Well"{
headerImg.image = UIImage(named: "icons8-happy-96")
}
if selectedActionPlan?.type == "Not Well"{
headerImg.image = UIImage(named: "icons8-sad-96")
}
if selectedActionPlan?.type == "Worse"{
headerImg.image = UIImage(named: "icons8-crying-96")
}
//for medicine
//<-------------------------BEGIN------------------------>
medicineList?.removeAll()
medicineList = selectedActionPlan?.contains?.allObjects as? [Medicine]
if medicineList?.count == 0{
//if actionplan has not been added yet
showForNoPlan()
}
if medicineList?.count == 1{
if medicineList![0].type == "Preventer"{
showForPreventer(p: medicineList![0])
}
else{
showForReliever(p: medicineList![0])
}
}
if medicineList?.count == 2 {
if medicineList![0].type == "Preventer"{
showForBoth(p: medicineList![0], r: medicineList![1])
}
else{
showForBoth(p: medicineList![1], r: medicineList![0])
}
}
//<-----------END---------------------------->
//setting additional information
if selectedActionPlan?.info == nil{
infoLabel.text = "No information added yet"
}
else{
infoLabel.text = selectedActionPlan?.info
}
//setting spacer use option
if (selectedActionPlan?.useSpencer)!{
ifUseSpencer.selectedSegmentIndex = 0
}
else{
ifUseSpencer.selectedSegmentIndex = 1
}
}
override func viewDidLoad() {
super.viewDidLoad()
@IBAction func addMedForPreventer(_ sender: Any) {
typeOfMedicineSelected = "Preventer"
//perform manual segue
self.performSegue(withIdentifier: "addMedSegue", sender: nil)
}
@IBAction func addMedForReliever(_ sender: Any) {
typeOfMedicineSelected = "Reliever"
//perform manual segue
self.performSegue(withIdentifier: "addRelieverSegue", sender: nil)
}
@IBAction func addInfoOnPress(_ sender: Any) {
self.performSegue(withIdentifier: "addInfoSegue", sender: nil)
}
//displays stuff when there is no action plan
func showForNoPlan(){
preventerName.text = "Empty"
preventerDescription.text = "Looks like you haven't entered anything yet."
buttonText.setTitle("Add", for: .normal)
preventerPic.image = UIImage(named: "icons8-box-important-48")
relieverName.text = "Empty"
relieverDescription.text = "Looks like you haven't entered anything yet."
rButtonText.setTitle("Add", for: .normal)
relieverPic.image = UIImage(named: "icons8-box-important-48")
}
//only preventer plan is there
func showForPreventer(p: Medicine){
preventerName.text = p.name
if p.isTablet{
//the medicine is a tablet
preventerDescription.text = "Take \(p.dosage!) tablets \(p.freq!) times every day"
preventerPic.image = UIImage(named: "icons8-pill-48")
}
else{
//the medicine is inhaler
preventerDescription.text = "Take \(p.dosage!) puffs \(p.freq!) times every day"
preventerPic.image = UIImage(named: "inhaler_2")
}
buttonText.setTitle("Edit", for: .normal)
relieverName.text = "Empty"
relieverDescription.text = "Looks like you haven't entered anything yet."
rButtonText.setTitle("Add", for: .normal)
relieverPic.image = UIImage(named: "icons8-box-important-48")
}
//only reliever plan is there
func showForReliever(p: Medicine){
//aa reliever is always an inhaler (add this to the addMedicine section)
//also, no fixed day times
relieverName.text = p.name
relieverDescription.text = "Take \(p.dosage!) puffs."
rButtonText.setTitle("Add", for: .normal)
relieverPic.image = UIImage(named: "inhaler_2")
preventerName.text = "Empty"
preventerDescription.text = "Looks like you haven't entered anything yet."
buttonText.setTitle("Edit", for: .normal)
preventerPic.image = UIImage(named: "icons8-box-important-48")
}
//both plans are there
func showForBoth(p: Medicine, r: Medicine){
preventerName.text = p.name
if p.isTablet{
//the medicine is a tablet
preventerDescription.text = "Take \(p.dosage!) tablets \(p.freq!) times every day"
preventerPic.image = UIImage(named: "icons8-pill-48")
}
else{
//the medicine is inhaler
preventerDescription.text = "Take \(p.dosage!) puffs \(p.freq!) times every day"
preventerPic.image = UIImage(named: "inhaler_2")
}
buttonText.setTitle("Edit", for: .normal)
relieverName.text = r.name
relieverDescription.text = "Take \(r.dosage!) puffs."
rButtonText.setTitle("Edit", for: .normal)
relieverPic.image = UIImage(named: "inhaler_2")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//delegate implementation for preventer
func sendMedData(name: String, type: String, isTablet: Bool, dosage: String, freq: String){
//generating a random number for the stock
let randomStock = Int(arc4random_uniform(3))
//temporary object store
let tempMed: Medicine = createManagedMedicine(dosage: dosage, freq: freq, isTablet: isTablet, type: type, name: name, stock: String(randomStock))
if medicineList?.count == 0{
//if no data, add whatever is being sent
selectedActionPlan?.addToContains(tempMed)
//save
saveData()
//<----------------------------display----------------------->
}
else{
//delete the old object
for eachMed in medicineList!{
if eachMed.type == tempMed.type{
oldMed = eachMed
}
}
if oldMed != nil{
managedObjectContext?.delete(oldMed!)
//add new object
selectedActionPlan?.addToContains(tempMed)
//save
saveData()
}
else{
//if no data, add whatever is being sent
selectedActionPlan?.addToContains(tempMed)
//save
saveData()
}
//<---------------------display---------------------->
//if newly added medicing is a preventer
// preventerName.text = tempMed.name
// if tempMed.isTablet{
// //the medicine is a tablet
// preventerDescription.text = "Take \(tempMed.dosage!) tablets \(tempMed.freq!) times every day"
// preventerPic.image = UIImage(named: "icons8-pill-48")
// }
// else{
// //the medicine is inhaler
// preventerDescription.text = "Take \(tempMed.dosage!) puffs \(tempMed.freq!) times every day"
// preventerPic.image = UIImage(named: "inhaler_2")
// }
// buttonText.setTitle("Edit", for: .normal)
}
}
//delegate implementation for reliever
func sendRelieverData(name: String, type: String, isTablet: Bool, dosage: String, freq: String) {
//generating a random number for the stock
let randomStock = Int(arc4random_uniform(50))
//temporary object store
let tempMed: Medicine = createManagedMedicine(dosage: dosage, freq: freq, isTablet: isTablet, type: type, name: name, stock: String(randomStock))
if medicineList?.count == 0{
//if no data, add whatever is being sent
selectedActionPlan?.addToContains(tempMed)
//save
saveData()
//<----------------------------display----------------------->
//if newly added medicing is a reliever
relieverName.text = tempMed.name
relieverDescription.text = "Take \(tempMed.dosage!) puffs."
rButtonText.setTitle("Edit", for: .normal)
relieverPic.image = UIImage(named: "inhaler_2")
}
else{
//delete the old object
for eachMed in medicineList!{
if eachMed.type == tempMed.type{
oldMed = eachMed
}
}
if oldMed != nil{
managedObjectContext?.delete(oldMed!)
//add new object
selectedActionPlan?.addToContains(tempMed)
//save
saveData()
}
else{
//this does not exist yet
selectedActionPlan?.addToContains(tempMed)
//save
saveData()
}
//<---------------------display---------------------->
//if newly added medicing is a reliever
relieverName.text = tempMed.name
relieverDescription.text = "Take \(tempMed.dosage!) puffs."
rButtonText.setTitle("Edit", for: .normal)
relieverPic.image = UIImage(named: "inhaler_2")
}
}
//duplicate function for creating managed medicine objects
func createManagedMedicine(dosage: String, freq: String, isTablet: Bool, type: String, name: String, stock: String) -> Medicine {
let med = NSEntityDescription.insertNewObject(forEntityName: "Medicine", into: managedObjectContext!) as! Medicine
med.dosage = dosage
med.freq = freq
med.isTablet = isTablet
med.type = type
med.name = name
med.stock = stock
return med
}
func saveData(){
do{
try managedObjectContext?.save()
}
catch let error{
print("could not save to core data: \(error)")
}
}
//delegate implementation for information tab
func sendInfoData(info: String) {
//infoLabel.text = info
//gonna type some sort of an update function.
//Hope this works!
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "ActionPlan")
fetchRequest.predicate = NSPredicate(format: "type = %@", (selectedActionPlan?.type)!)
do{
let test = try managedObjectContext?.fetch(fetchRequest)
let objectUpdate = test![0] as! NSManagedObject
objectUpdate.setValue(info, forKey: "info")
do{
try managedObjectContext?.save()
}
catch{
print(error)
}
}
catch{
print(error)
}
}
//duplicate helper function
func createManagedActionPlan(type: String, useSpencer: Bool, info: String) -> ActionPlan {
let plan = NSEntityDescription.insertNewObject(forEntityName: "ActionPlan", into: managedObjectContext!) as! ActionPlan
plan.type = type
plan.useSpencer = useSpencer
plan.info = info
return plan
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "addMedSegue"{
let controller: AddMedicineViewController = segue.destination as! AddMedicineViewController
if medicineList?.count != 0{
for each in medicineList!{
if each.type == "Preventer"{
controller.selectedMed = each
controller.isMedEmpty = false
}
}
}
else{
controller.isMedEmpty = true
}
controller.delegate = self
}
if segue.identifier == "addRelieverSegue"{
let controller: AddRelieverViewController = segue.destination as! AddRelieverViewController
if medicineList?.count != 0{
for each in medicineList!{
if each.type == "Reliever"{
controller.selectedMed = each
controller.isMedEmpty = false
}
}
}
else{
controller.isMedEmpty = true
}
controller.delegate = self
}
if segue.identifier == "addInfoSegue"{
let controller: AddInfoViewController = segue.destination as! AddInfoViewController
//controller.type = typeOfMedicineSelected
if selectedActionPlan?.info != "No information added yet."{
controller.selectedActionPlan = selectedActionPlan
controller.isInfoEmpty = false
}
else{
controller.isInfoEmpty = true
}
controller.delegate = self
}
}
}