NSCoding 游戏数据未保存 swift

NSCoding gamedata not saved swift

目前,我的数据没有在另一个新会话中检索到,它使用默认值。我必须有一个现有的 plist 文件才能工作吗?我尝试使用现有文件,但没有成功。

我按照这里的指南http://battleofbrothers.com/sirryan/saving-game-data-in-spritekit

class GameData : NSObject, NSCoding {

/// Data to save

var variableC : Int = 3

/// Create of shared instance

class var sharedInstance: GameData {

    struct Static {
        static var instance: GameData?
        static var token: dispatch_once_t = 0
    }

    dispatch_once(&Static.token) {
        var gamedata = GameData()
        if let savedData = GameData.loadGame() {
            gamedata = savedData
        }
        Static.instance = gamedata
    }

    return Static.instance!
}

override init() {
    super.init()
}

required init(coder: NSCoder) {
    super.init()
}

func encodeWithCoder(coder: NSCoder) {
    coder.encodeObject(GameData.sharedInstance, forKey: "GameData")
}

class func loadGame() -> GameData? {
    // load existing high scores or set up an empty array
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    let documentsDirectory = paths[0] as! String
    let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist")
    let fileManager = NSFileManager.defaultManager()

    // check if file exists
    if !fileManager.fileExistsAtPath(path) {
        // create an empty file if it doesn't exist
        println("File doesn't exist")
        if let bundle = NSBundle.mainBundle().pathForResource("DefaultFile", ofType: "plist") {
            fileManager.copyItemAtPath(bundle, toPath: path, error:nil)
        }
    }

    if let rawData = NSData(contentsOfFile: path) {
        // do we get serialized data back from the attempted path?
        // if so, unarchive it into an AnyObject, and then convert to an array of HighScores, if possible
        if let data = NSKeyedUnarchiver.unarchiveObjectWithData(rawData) as? GameData {
            println("We loaded the data!")
            return data
        }
    }
    println("we returned Nil")
    return nil
}

func save() {
    // find the save directory our app has permission to use, and save the serialized version of self.scores - the HighScores array.
    let saveData = NSKeyedArchiver.archivedDataWithRootObject(GameData.sharedInstance);
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray;
    let documentsDirectory = paths.objectAtIndex(0)as! NSString;
    let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist");

    saveData.writeToFile(path, atomically: true);
}

}

我用这个在初始化函数中加载游戏数据

var gameData: GameData = GameData.sharedInstance

更新数据

    gameData.variableC = gameData.variableC + 1
    gameData.save()
    println(gameData.variableC)

您保存数据但不在您的 init 中使用它。在 initWithCoder:

required init(coder: NSCoder) {
        super.init()
        GameData.shaderInstance = coder.decodeObjectForKey("GameData")
    }

正如 Jozsef 所说,我忘记解码数据了。但是我需要解码每个单独的变量,然后将其复制到 GameData 才能工作。

这是

class GameData : NSObject, NSCoding {

/// Data to save

var variableC : Int! = 3

/// Create of shared instance

class var sharedInstance: GameData {

    struct Static {
        static var instance: GameData?
        static var token: dispatch_once_t = 0
    }

    dispatch_once(&Static.token) {
        var gamedata = GameData()
        if let savedData = GameData.loadGame() {
            gamedata.variableC = savedData.variableC
        }
        Static.instance = gamedata
    }

    return Static.instance!
}

override init() {
    super.init()
}

required init(coder: NSCoder) {
    super.init()
    self.variableC = coder.decodeObjectForKey("variableC") as? Int

}

func encodeWithCoder(coder: NSCoder) {
    coder.encodeObject(GameData.sharedInstance.variableC, forKey: "variableC")
}

class func loadGame() -> GameData? {
    // load existing high scores or set up an empty array
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    let documentsDirectory = paths[0] as! String
    let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist")
    let fileManager = NSFileManager.defaultManager()

    // check if file exists
    if !fileManager.fileExistsAtPath(path) {
        // create an empty file if it doesn't exist
        println("File doesn't exist")
        if let bundle = NSBundle.mainBundle().pathForResource("DefaultFile", ofType: "plist") {
            fileManager.copyItemAtPath(bundle, toPath: path, error:nil)
        }
    }

    if let rawData = NSData(contentsOfFile: path) {
        // do we get serialized data back from the attempted path?
        // if so, unarchive it into an AnyObject, and then convert to an array of HighScores, if possible
        if let data = NSKeyedUnarchiver.unarchiveObjectWithData(rawData) as? GameData {
            println("We loaded the data!")
            return data
        }
    }
    return nil
}

func save() {
    // find the save directory our app has permission to use, and save the serialized version of self.scores - the HighScores array.
    let saveData = NSKeyedArchiver.archivedDataWithRootObject(GameData.sharedInstance);
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray;
    let documentsDirectory = paths.objectAtIndex(0)as! NSString;
    let path = documentsDirectory.stringByAppendingPathComponent("GameData.plist");

    saveData.writeToFile(path, atomically: true);
}

}