Search code examples
swiftstructnsarraynsuserdefaults

STRUCT Array To UserDefaults


I have a custom Struct class to hold calories, fats, carbs, and protein.

Each Time a user enters the data I put it into a variable

 var theArray : NSMutableArray = []

struct CFCPstruct {
    let calories : Int!
    let fats : Int!
    let carbs : Int!
    let protein: Int!
    init(Calories: Int, Fats: Int, Carbs: Int, Protein: Int) {
        self.calories = Calories
        self.fats = Fats
        self.carbs = Carbs
        self.protein = Protein
    }
}

 let addLog = [CFCPstruct(Calories: totalCalories, Fats: totalFats, Carbs: totalCarbs, Protein: totalProtein)]

Now I also created an array to store everything. I then need to store all the values into array, which then store that to UserDefaults.

Then I will need to call the user defaults call array[0] lets say and then call each calorie, carb, ... something like thelog.calories // theology.carbs etc


Solution

  • To be able to use NSCoding the object must be a class. But as all values are property list compliant you could add a variable dictionaryRepresentation and a corresponding initializer.

    First of all never use NSMutableArray in Swift and never declare variables as implicit unwrapped optional which are initialized with a non-optional initializer.

    var theArray = [CFCPstruct]()
    
    struct CFCPstruct  {
        let calories : Int
        let fats : Int
        let carbs : Int
        let protein: Int
    
        init(calories: Int, fats: Int, carbs: Int, protein: Int) {
            self.calories = calories
            self.fats = fats
            self.carbs = carbs
            self.protein = protein
        }
    
        init(dictionary : [String:Int]) {
            self.calories = dictionary["calories"]!
            self.fats = dictionary["fats"]!
            self.carbs = dictionary["carbs"]!
            self.protein = dictionary["protein"]!
        }
    
        var dictionaryRepresentation : [String:Int] {
            return ["calories" : calories, "fats" : fats, "carbs" : carbs, "protein" : protein]
        }
    }
    

    Now you can read the array from and write to user defaults.

    func saveDefaults() 
    {
        let cfcpArray = theArray.map{ $0.dictionaryRepresentation }
        UserDefaults.standard.set(cfcpArray, forKey: "cfcpArray")
    }
    
    func loadDefaults()
    {
        theArray = (UserDefaults.standard.object(forKey: "cfcpArray") as! [[String:Int]]).map{ CFCPstruct(dictionary:$0) }
    }