How to save an array of custom structs to plist swift

Posted on

How to save an array of custom structs to plist swift

I’m trying to save alert data to a plist, it is in the form of an array of the class alertData, all the info i can find points to encoding it, and then putting it in the array, but i’m confused as to what this does? And i also can’t figure out how to do it, here’s my playground: Any help would be great

The class (i’m trying to save an array of these)

public class alertData: NSObject, NSCoding {
//Properties of the timer data - make optionals optional i.e. alert count etc.

var alertCounter: NSTimeInterval?
var alertText: String?
var alertColor: UIColor?
var alertColorIndex: Int?


//initialisation
init(alertCounter: Double, alertText: String, alertColor: UIColor, alertColourIndex: Int) {

    self.alertCounter = alertCounter
    self.alertText = alertText
    self.alertColor = alertColor
    self.alertColorIndex = alertColourIndex
}

public required init(coder aDecoder: NSCoder) {
    alertCounter = aDecoder.decodeDoubleForKey("Item1")
    alertText = aDecoder.decodeObjectForKey("Item2") as? String
    alertColor = aDecoder.decodeObjectForKey("Item3") as? UIColor
    alertColorIndex = aDecoder.decodeIntegerForKey("Item4")
}

public func encodeWithCoder(aCoder: NSCoder) {
    alertCounter = aCoder.decodeDoubleForKey("Item1")
    alertText = aCoder.decodeObjectForKey("Item2") as? String
    alertColor = aCoder.decodeObjectForKey("Item3") as? UIColor
    alertColorIndex = aCoder.decodeIntegerForKey("Item4")
}
}

The array (becomes populated when i add alert data in the app):

var alertDataSource: [alertData] = []

And to encode it:

let archive = NSKeyedArchiver.archivedDataWithRootObject(self.alertDataSource)
            print(archive)

And to extract it:

let result = NSKeyedUnarchiver.unarchiveObjectWithData(archive)
            print(result)

Thanks in advance for any tips / advice

Solution :

You’re not meant to call encodeWithCoder() yourself. Use NSKeyedArchiver and NSKeyedUnarchiver. The init(coder:) and encodeWithCoder() will be called as needed by the archiver / unarchiver.

Place your NSCoding-compliant alertData instances (this should really be AlertData since class names should be proper case) into an array (or dictionary if you please) and do this:

let archive = NSKeyedArchiver.archivedDataWithRootObject(yourArrayOfAlertData)

In this case, archive will be an NSData instance.

Update

Actually, I guess I missed it the first time, but your encode...() method isn’t right. At all. Consider the difference with:

public func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeDouble(alertCounter, forKey:"Item1")
    aCoder.encodeObject(alertText, forKey:"Item2")
    aCoder.encodeObject(alertColor , forKey:"Item3")
    aCoder.encodeInteger(alertColorIndex, forKey:"Item4")
}

(Also consider naming your keys the same as their properties, like "alertCounter" for alertCounter.)

Leave a Reply

Your email address will not be published. Required fields are marked *