2015-05-31 15 views
5

Próbuję stworzyć moją pierwszą grę błyskawiczną zestawu sprite i mam dane mojej gry działające przy użyciu nsuserdefaults. Chcę uczynić go bardziej bezpiecznym, więc próbuję przejść na NSCoding, ale nic, co znalazłem online, nie pomogło mi całkowicie i właśnie mnie pomyliło (przepraszam jeśli odpowiedź już istnieje, prawdopodobnie już na nią patrzyłem i nie było „t stanie zrozumieć)Zmiana z NSUserDefaults na NSCoding

to moja klasa 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() 
} } 

i zapisać i ładowania danych w moich innych klas przy użyciu:

GameState.sharedInstance.***** 

Jak bym go o zmianę tego zaimplementować NSCoding, a następnie załadować i zapisać dane z innych klas? Dzięki.

Odpowiedz

2

Klasa, którą chcesz zapisać, musi być zgodna z protokołem NSCoding i implementować required init(coder aDecoder: NSCoder) i func encodeWithCoder(aCoder: NSCoder).

Oto uproszczony przykład:

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) 

Następnie można użyć NSKeyedArchiver i NSKeyedUnarchiver, na przykład w AppDelegate, aby zapisać i załadować obiekt danych:

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

dzięki za odpowiedź, tylko kilka pytań: to "pozwól myGameState ...", czego używasz zamiast oryginalnej klasy init(), aby dodać wartości do każdej zmiennej? Jak mogę zaktualizować gamestate z innych klas? (aby zaktualizować wynik i dźwięk itp.) dziękuję – AEkon

+0

Nie ma za co. To tylko init z parametrami, które przygotowałem dla mojego przykładu, nie musisz zmieniać swojego. Trzeba tylko zaimplementować "wymagany" i upewnić się, że tutaj są zadeklarowane wszystkie właściwości, które chcesz wczytać. – Moritz

+0

oh dobrze chory, spróbuj jeszcze raz dzięki! dla pliku toFile w appdelegate, w jaki sposób zapisać go na używanym telefonie? dzięki – AEkon