从NSUserDefaults更改为NSCoding

AEk*_*kon 5 nsuserdefaults nscoding ios sprite-kit swift

我正在尝试创建我的第一个sprite kit swift游戏,并且我的游戏数据使用nsuserdefaults.我想让它更安全,所以我试图过渡到NSCoding,但我在网上找到的任何东西都没有完全帮助我,只是让我感到困惑(很抱歉,如果答案已经存在,我可能已经看过它并且没有能够理解.)

这是我的GameState类:

class GameState {
var score: Int
var highScore: Int
var stars: Int
var sound: Bool
var carType: Int
var xSize: Double
var ySize: Double
var gameOver: Bool

class var sharedInstance: GameState {
    struct Singleton {
        static let instance = GameState()
    }

    return Singleton.instance
}

init() {
    // Init
    score = 0
    highScore = 0
    stars = 0
    carType = 1
    sound = true
    xSize = 1
    ySize = 1
    gameOver = false

    // Load game state
    let defaults = NSUserDefaults.standardUserDefaults()

    highScore = defaults.integerForKey("highScore")
    stars = defaults.integerForKey("stars")
    sound = defaults.boolForKey("sound")
    carType = defaults.integerForKey("carType")
    xSize = defaults.doubleForKey("xSize")
    ySize = defaults.doubleForKey("ySize")
    gameOver = defaults.boolForKey("gameOver")
}


func saveState() {
    // Update highScore if the current score is greater
    highScore = max(score, highScore)

    // Store in user defaults
    let defaults = NSUserDefaults.standardUserDefaults()
    defaults.setInteger(highScore, forKey: "highScore")
    defaults.setInteger(stars, forKey: "stars")
    defaults.setBool(sound, forKey: "sound")
    defaults.setInteger(carType, forKey: "carType")
    defaults.setDouble(xSize, forKey: "xSize")
    defaults.setDouble(ySize, forKey: "ySize")
    defaults.setBool(gameOver, forKey: "gameOver")
    NSUserDefaults.standardUserDefaults().synchronize()
} }
Run Code Online (Sandbox Code Playgroud)

我使用以下方法在我的其他类中保存和加载数据:

GameState.sharedInstance.*****
Run Code Online (Sandbox Code Playgroud)

我将如何更改此实现NSCoding,然后从其他类加载和保存数据?谢谢.

aya*_*aio 2

您要保存的类必须符合NSCoding协议并实现required init(coder aDecoder: NSCoder)func encodeWithCoder(aCoder: NSCoder)

这是一个简化的示例:

class GameState: NSObject, NSCoding {

    var score: Int?
    var gameOver: Bool?

    init(score: Int, gameOver: Bool) {
        super.init()
        self.score = score
        self.gameOver = gameOver
    }

    required init(coder aDecoder: NSCoder) {
        self.score = aDecoder.decodeObjectForKey("score") as? Int
        self.gameOver = aDecoder.decodeObjectForKey("gameOver") as? Bool
    }

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

}

let myGameState = GameState(score: 42, gameOver: true)
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用NSKeyedArchiverNSKeyedUnarchiver,例如在 AppDelegate 中,将对象作为数据保存和加载:

func applicationWillTerminate(aNotification: NSNotification) {
    NSKeyedArchiver.archiveRootObject(myGameState, toFile: "a/file/path")
}

func applicationDidFinishLaunching(aNotification: NSNotification) {
    if let data = NSKeyedUnarchiver.unarchiveObjectWithFile("a/file/path") as? GameState {
        myGameState = data
    }
}
Run Code Online (Sandbox Code Playgroud)