CoolMAn CoolMAn - 4 days ago 5
Swift Question

cannot save UserDefault array in certain iPhone simulators (swift 3)

I'm saving an array using

UserDefault
and for the most part it's working incredibly great. However in some simulators such as iPhone 7, iPhone 5 (iOS 9.3), and iPhone 6 (iOS 9.3) the simulator crashes in the line where I try loading one of my arrays from UserDefaults.

@IBAction func AddGraphComponent(_ sender: UIButton) {
var weighText:UITextField!
let alert = UIAlertController(title: "Enter new Weight!", message: "Please enter your Weight, followed by the date in which your weight was recorded", preferredStyle: UIAlertControllerStyle.alert)
alert.addTextField { (weighText) in
weighText.placeholder = "Weight"
weighText.keyboardType = UIKeyboardType.numberPad
}
alert.addTextField { (dateText) in
dateText.placeholder = "Date (MM/YY)"
}
let confirmAction = UIAlertAction(title: "Save", style: UIAlertActionStyle.default) { (_) in
let field = alert.textFields![0] as? UITextField
let weigh = alert.textFields![1] as? UITextField
if (field?.text)! == "" || (weigh?.text)! == "" {
let alert1 = UIAlertController(title: "Error!", message: "Please fill in BOTH fields", preferredStyle: UIAlertControllerStyle.alert)
alert1.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert1, animated: true, completion: nil)
}else {
print((field?.text)!,(weigh?.text)!)
let dataInt:Int = Int((field?.text!)!)!
self.chartData.append(dataInt)
self.chartLegend.append((weigh?.text)!)

var weighting = UserDefaults.standard.array(forKey: "chartData") as! [Int]
var dating = UserDefaults.standard.array(forKey: "chartLegend") as! [String]// this is where the error is EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP,subcode=0x0)

weighting.append((dataInt))
dating.append((weigh?.text)!)


self.kUserDefault.set(weighting, forKey: "chartData")
self.kUserDefault.set(dating, forKey: "chartLegend")
self.kUserDefault.synchronize()

self.lineChart.reloadData()

print("\((dating))")
print("\((weighting))")
}
}
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
alert.addAction(confirmAction)
self.present(alert, animated: true, completion: nil)
}


at the line where I write
var dating = UserDefaults.standard.array(forKey: "chartLegend") as! [String]
my code crashes on said device simulators. I wonder as to why this is. Is there an error in my code, or is this a bug?
I'm using swift 3 on Xcode 8.0

Answer

This is happening most likely because UserDefaults doesn't find anything named 'chartData' or 'chartLegend' and then reading it as nil. What you want to do is use a if let to safely check if there is a value you can receive.

Take a look here:

if let weighting = UserDefaults.standard.array(forKey: "chartData") as? [Int] {
    //Do your stuff
    weighting.append((dataInt))
    self.kUserDefault.set(weighting, forKey: "chartData")
    print("\((weighting))")
}
if let dating = UserDefaults.standard.array(forKey: "chartLegend") as? [String] {
    //do your stuff here
    dating.append((weigh?.text)!)
    self.kUserDefault.set(dating, forKey: "chartLegend")
     print("\((dating))")
}
self.kUserDefault.synchronize()

As rmaddy commented, it is important that you do a clean install on simulator and real device before testing modified code, especially when you are dealing with read/write from storage.

Comments