Search code examples
iosswiftsaveplist

How do I write this data into my Plist? - Swift


I'm very close to writing new data back into my UserData.plist, but I'm having an issue creating the new data's dictionary correctly so it can write out.

func saveTriggerData(){

    //get current date
    let date = NSDate()

    //for each trigger, insert date,value
    for (index,trigger) in enumerate(triggersList){
        //if trigger already exists in userData, just add a new date, value
        if(triggersData[trigger] != nil){
            NSLog("Trigger " + trigger + " exists")
            //get value of corresponding stepper
            var value = Int(steppersList[index].value)
            //get previous data for this trigger

            //make a dictionary of new data
            var newData: [NSDate: NSNumber] = [date: value]
            triggersData.addEntriesFromDictionary(newData)

            //insert new data
            let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
            let documentsDirectory = paths.objectAtIndex(0) as NSString
            let path = NSBundle.mainBundle().pathForResource("UserData", ofType: "plist")
            //replace dict's Triggers value with our new Triggers
            NSLog("\(userData)")
            //userData.setObject(triggersData, forKey:"Triggers")
            //let fileWritten = userData.writeToFile(path!, atomically: true)
            //NSLog("Save trigger data: \(fileWritten)")

        }
        else{ //trigger does not yes exist in userData, add trigger name and then its date, value
           NSLog("Trigger " + trigger + " does not yet exist")
        }

    }

}

Results:

Triggers =     {
        "Caffeinated Drinks" =         (
                        (
                "2014-12-03 16:30:22 +0000",
                2
            ),
                        (
                "2014-12-04 16:30:02 +0000",
                1
            )
        );
        "Alcoholic Drinks" =         (
                        (
                "2014-12-03 16:28:53 +0000",
                3
            ),
                        (
                "2014-12-04 16:29:33 +0000",
                0
            )
        );
        "2014-12-15 23:36:53 +0000" = 0;
    };
}

The last line "2014-12-15 23:36:53 +0000" = 0; should be a child of Alcoholic Drinks. So, I'm close, but I'm not all the way there yet, and I'm going crazy over it. Any help would be greatly appreciated.

Oh, and the plist:

<key>Triggers</key>
    <dict>
        <key>Alcoholic Drinks</key>
        <array>
            <array>
                <date>2014-12-03T16:28:53Z</date>
                <integer>3</integer>
            </array>
            <array>
                <date>2014-12-04T16:29:33Z</date>
                <integer>0</integer>
            </array>
        </array>
        <key>Caffeinated Drinks</key>
        <array>
            <array>
                <date>2014-12-03T16:30:22Z</date>
                <integer>2</integer>
            </array>
            <array>
                <date>2014-12-04T16:30:02Z</date>
                <integer>1</integer>
            </array>
        </array>
    </dict>

Solution

  • Your triggersData is a dictionary containing arrays of arrays. You are currently adding newData (which is a dictionary of numbers keyed on dates) to the end of that. You need instead to create an array from your date and value, and to append that array to the relevant item in your dictionary. So, instead of:

    var newData: [NSDate: NSNumber] = [date: value]
    triggersData.addEntriesFromDictionary(newData)
    

    try:

    var newData : [AnyObject] = [date, value]
    if var triggerArray = triggersData[trigger] as? [AnyObject] {
        triggerArray.append(newData)
        triggersData[trigger] = triggerArray
    }
    

    That will get the data into the same form as your plist. But if I were you I would restructure your plist - the lowest level arrays have to be [AnyObject] because the first item is of type NSDate while the second item is of type NSNumber, which is a bad idea.