Peter71
Peter71

Reputation: 2310

iOS Swift: does not save pList with class

I try to save my own class "Solutions" in a pList. It contains an array of another class "Solution".

let dict: NSMutableDictionary = ["XInitializerItem": Solution() ]
// saving values
dict.setObject(solutions, forKey: "best")

// writing back
dict.writeToFile(path, atomically: false)

But file is not written. I think it depends on the class. With simple datatypes like String or Int is works. What is missing?

I add some code fragments:

func savePlist( solutions : [Solution]) {

    let path = getDocPath(plistfile + ".plist")

    let dict: NSMutableDictionary = ["XInitializerItem": Solution() ]
    // saving values
    dict.setObject(solutions, forKey: "best")

    // writing back
    dict.writeToFile(path, atomically: false)

}

Solution is defined as:

class Solution : NSObject, NSCoding {   // struct
    let word     : String
    let score    : Int
    let priority : Int      // needed for sorting criteria
    let turn     : Int      // when was this reached?
    let date     : NSDate   // same
    let width    : Int      // which dimenions of the game?
    let height   : Int
    var new      : Bool     // in this session (or loaded from best list)

    init(word : String = "", score : Int = 0, bonus : Int = 0, turn : Int = 0, new : Bool = true) {
        self.word = word
        self.score = score
        self.priority = score + bonus
        self.turn = turn
        self.date = NSDate()
        self.width = NumColumns
        self.height  = NumRows
        self.new  = new
    }

    required init(coder aDecoder: NSCoder) {
        word     = aDecoder.decodeObjectForKey("word")     as! String
        score    = aDecoder.decodeObjectForKey("score")    as! Int
        priority = aDecoder.decodeObjectForKey("priority") as! Int
        turn     = aDecoder.decodeObjectForKey("turn")     as! Int
        date     = aDecoder.decodeObjectForKey("date")     as! NSDate
        width    = aDecoder.decodeObjectForKey("width")    as! Int
        height   = aDecoder.decodeObjectForKey("height")   as! Int
        new      = false
    }

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(word, forKey: "word")
        aCoder.encodeObject(score, forKey: "score")
    }
}

class Solutions : NSObject, NSCoding {
    var solutions = [Solution]()   // for high score etc...

    override init() {
    }

    func bestSolution() -> Solution? {
        if solutions.count == 0 { return nil }
        var best = solutions[0]
        for s in solutions {
            if s.score > best.score {
                best = s
            }
        }
        return best
        //           return Solutions.reduce(0, { max($0.score, $1.score) })
    }

    func longestSolution() -> Solution? {
        if solutions.count == 0 { return nil }
        var best = solutions[0]
        for s in solutions {
            if s.word.characters.count > best.word.characters.count {
                best = s
            }
        }
        return best
        //           return Solutions.reduce(0, { max($0.score, $1.score) })
    }

    required init(coder aDecoder: NSCoder) {
        solutions = aDecoder.decodeObjectForKey("solutions") as! [Solution]
    }

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(solutions, forKey: "solutions")
    }
}

Upvotes: 0

Views: 118

Answers (1)

zaph
zaph

Reputation: 112873

In order to write a plist with a user generated class the class needs to support the NSCoding protocol.

From Introduction to Property Lists:

But if objects conform to the NSCoding protocol they can be archived to NSData objects, which are property list–compatible objects.

Upvotes: 1

Related Questions