2015-05-31 21 views
5

Sto provando a creare il mio primo gioco di sprite kit swift, e ho i miei dati di gioco che funzionano utilizzando nsuserdefaults. Voglio renderlo più sicuro, quindi sto tentando di passare a NSCoding, ma nulla di quello che ho trovato online mi ha aiutato completamente e mi ha semplicemente confuso (mi spiace quindi se esiste già una risposta, probabilmente l'ho già vista e wasn 't in grado di capire)Modifica da NSUserDefaults a NSCoding

questa è la mia classe 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() 
} } 

e salvare e caricare dati nelle mie altre classi utilizzando:

GameState.sharedInstance.***** 

Come posso fare per cambiare questo implementare NSCoding e quindi caricare e salvare i dati da altre classi? Grazie.

risposta

2

La classe che si desidera salvare deve essere conforme al protocollo NSCoding e implementare required init(coder aDecoder: NSCoder) e func encodeWithCoder(aCoder: NSCoder).

Ecco un esempio semplificato:

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) 

quindi è possibile utilizzare NSKeyedArchiver e NSKeyedUnarchiver, per esempio nel AppDelegate, per salvare e caricare l'oggetto come dati:

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

Grazie per la risposta, solo alcune domande: è 'lascia myGameState ...' cosa usi al posto della classe init() originale per aggiungere valori a ogni variabile? come aggiornerei il gamestate dalle altre classi? (per aggiornare punteggio e suono, ecc.) grazie – AEkon

+0

Prego. È solo un init con i parametri che ho fatto per il mio esempio, non devi cambiare il tuo. Devi solo implementare quello "richiesto" e assicurarti che tutte le proprietà che vuoi caricare siano dichiarate qui. – Moritz

+0

oh, va bene, prova che grazie ancora! per toFile nell'appdelegate, come potrei salvarlo sul telefono utilizzato? grazie – AEkon