2015-05-31 18 views
5

Ich versuche mein erstes Sprite-Kit-Swift-Spiel zu erstellen, und meine Spieldaten funktionieren mit nsuserdefaults. Ich möchte es sicherer machen, also versuche ich auf NSCoding umzusteigen, aber nichts, was ich online gefunden habe, hat mir völlig geholfen und mich verwirrt (tut mir leid, wenn eine Antwort schon existiert, ich habe es wahrscheinlich schon angeschaut und warn ‚t in der Lage zu verstehen)Von NSUserDefaults zu NSCoding wechseln

Das ist mein GameState Klasse.

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() 
} } 

und ich laden und speichern Daten in meinen anderen Klassen:

GameState.sharedInstance.***** 

Wie würde ich mich über diese Veränderung um NSCoding zu implementieren und dann die Daten aus anderen Klassen zu laden und zu speichern? Vielen Dank.

Antwort

2

Die Klasse, die Sie sichern möchten, muss dem Protokoll NSCoding entsprechen und required init(coder aDecoder: NSCoder) und func encodeWithCoder(aCoder: NSCoder) implementieren.

Hier ist ein vereinfachtes Beispiel:

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) 

Dazu NSKeyedArchiver und NSKeyedUnarchiver, zum Beispiel in der AppDelegate, Ihr Objekt als Daten zu speichern und laden können:

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 
    } 
} 
+0

Vielen Dank für Ihre Antwort, nur ein paar Fragen: ist 'let myGameState ...' was Sie anstelle der ursprünglichen init() -Klasse verwenden, um Werte zu jeder Variablen hinzuzufügen? Wie würde ich den Gamestate von den anderen Klassen aktualisieren? (um Punktestand und Ton usw. zu aktualisieren) danke – AEkon

+0

Gern geschehen. Es ist nur ein Init mit Parametern, die ich für mein Beispiel gemacht habe, du musst deine nicht ändern. Sie müssen nur die "erforderliche" implementieren und sicherstellen, dass alle Eigenschaften, die Sie laden möchten, hier deklariert sind. – Moritz

+0

oh in Ordnung krank versuchen, dass noch einmal vielen Dank! für die toFile in der AppDelegate, wie würde ich es auf dem Telefon zu speichern? danke – AEkon