0

I am using UserDefaults to store data, specifically an array of type Workout. In the Workout class is an array of type Exercise. When I call the save function to persist the data, the code crashes when encoding the Exercise array. What am I doing wrong with my setup?

enum Type: String {
    case Interval
    case Count
}

class Exercise: NSObject, NSCoding{
    var reps: Int = 1
    var numberOf: Int = 1
    var name: String = "New Exercise"
    var type: Type = .Interval

    func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: "exerciseName")
        aCoder.encode(reps, forKey: "exerciseReps")
        aCoder.encode(type, forKey: "exerciseType")
        aCoder.encode(numberOf, forKey: "exerciseNumberOf")
    }

    required init(coder aDecoder: NSCoder) {
        name = aDecoder.decodeObject(forKey: "exerciseName") as! String
        reps = aDecoder.decodeObject(forKey: "exerciseReps") as! Int
        numberOf = aDecoder.decodeObject(forKey: "exerciseNumberOf") as! Int
        type = aDecoder.decodeObject(forKey: "exerciseType") as! Type

        super.init()
    }

    override init() {
        super.init()
    }

}

class Workout: NSObject, NSCoding {
    var name: String = "My Workout"
    var lastUsedDate: Date? = nil
    var exerciseList: [Exercise] = []


    func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: "name")
        aCoder.encode(lastUsedDate, forKey: "lastUsedDate")

        // Code crashes here:
        aCoder.encode(exerciseList, forKey: "exerciseData")

    }

    required init(coder aDecoder: NSCoder) {
        super.init()

        self.name = aDecoder.decodeObject(forKey: "name") as! String
        self.lastUsedDate = aDecoder.decodeObject(forKey: "lastUsedDate") as? Date
        self.exerciseList = aDecoder.decodeObject(forKey: "exerciseData") as! [Exercise]
    }

    override init() {
        super.init()
    }
}

Save and load functions

func save() {
    let data = NSKeyedArchiver.archivedData(withRootObject: workouts )
    UserDefaults.standard.setValue(data, forKey: "data")

}

func load() {
    if let storedArray = UserDefaults.standard.object(forKey: "data") as? Data {
        workouts = NSKeyedUnarchiver.unarchiveObject(with: storedArray) as! [Workout]
    }
}
shavavo
  • 65
  • 1
  • 6
  • 1
    your problem it is probably here `enum Type` is not NSCoding compliant (note that you should name your cases starting with a lowercase letter. Another issue is `decodeObject(forKey: "exerciseReps") as! Int` you should use `decodeInteger(forKey:)` – Leo Dabus Jul 05 '17 at 21:58
  • 1
    @LeoDabus Yes, that was it! Thank you – shavavo Jul 05 '17 at 22:00

0 Answers0