Paul Dobbs
Paul Dobbs

Reputation: 35

write nested classes to plist

I have a pair of classes: Scale and WeightSet. Scale contains an array of WeightSet within it:

class Scale {
    var name: String
    var factor: Double
    var weights: [WeightSet] = []

    ...

 }

class WeightSet {
    var gauge: String
    var initial: Double
    var increment: Double
    var lengthUnit: String
    var weightUnit: String

   ...

}

There is an array of Scale:

var scales = [Scale]()

I have been able to create a plist in Xcode, copy it to the documents directory and read it in, but can't figure out how to write it back to the plist with changes. All the examples that I can find are for simple classes, and I don't know how to handle the nested array of WeightSets.

FYI, here is how I am reading it in:

func readScales() {

    //read the plist file into input
    let input = NSArray(contentsOfFile: path)

    //loop through input
    for i in 0..<input!.count {

        //convert each element of input into a dictionary
        let scaleDict = input![i] as! NSDictionary

        //create a Scale object from the dictionary values
        let scale = Scale(name: scaleDict.valueForKey("name") as! String, factor: scaleDict.valueForKey("factor") as! Double)

        //convert the weights entry of the dictionary into an array of dictionaries
        let weights = scaleDict.valueForKey("weights") as! [NSDictionary]

        //loop through the array
        for weight in weights {

            //create a WeightSet object for each dictionary
            let weightSet = WeightSet(gauge: weight.valueForKey("gauge") as! String, initial:  weight.valueForKey("initial") as! Double, increment:  weight.valueForKey("increment") as! Double, lengthUnit:  weight.valueForKey("lengthUnit") as! String, weightUnit:  weight.valueForKey("weightUnit") as! String)

            //append the WeightSet object to the Scale Object
            scale.weights.append(weightSet)
        }

        //append the Scale object to the scales array
        scales.append(scale)
    }

    //print it to prove this worked!
    printScales()
}

Upvotes: 1

Views: 409

Answers (1)

Duncan C
Duncan C

Reputation: 131481

You can't save custom objects to a property list. Property lists can only contain a short list of types (dictionaries, arrays, strings, numbers (integer and float), dates, binary data, and Boolean values).

It looks like you are saving an array of dictionaries to your property list rather than trying to save your custom classes directly, which is good.

You should create a pair of methods that convert your custom classes to/from property list objects.

Let's use your Scale object as an example.

Say you create a toDict method that converts a Scale object to a dictionary (containing other dictionaries and arrays if need be) and an init(dict dict: Dictionary) that creates a new Scale object from a dictionary.

You could use a map statement to convert an array of Scale objects to an array of dictionaries, or an array of dictionaries to an array of Scale objects.

Upvotes: 1

Related Questions