Skip to content

Instantly share code, notes, and snippets.

@veeneck
Created April 2, 2015 16:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save veeneck/724ad57982e7fa6214a3 to your computer and use it in GitHub Desktop.
Save veeneck/724ad57982e7fa6214a3 to your computer and use it in GitHub Desktop.
Current save game data
import SpriteKit
class GameData : NSObject, NSCoding {
/// Each scene always knows what scene should come next.
/// So, by storing the current scene, we can just resume that scene when the game is reloaded
/// If the user quits on a level, use logic to show world map instead
/// NOTE** -- save SceneObject instead? so that userData is remembered, and it just pass this to scene manager?
var currentScene : String = "MainMenu"
/// Reference to LevelData array which contains both static and saved data
var levelData : LevelData?
/// Reference to the current army
var army : ArmyData?
/// 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.levelData = savedData.levelData
gamedata.army = savedData.army
// hard code different setups for testing
// this will override the saved file
//gamedata.levelData?.setTestingData()
}
Static.instance = gamedata
}
return Static.instance!
}
override init() {
super.init()
self.levelData = LevelData()
self.army = ArmyData()
}
required init(coder: NSCoder) {
super.init()
self.currentScene = coder.decodeObjectForKey("currentScene") as! String
self.levelData = coder.decodeObjectForKey("levelData") as? LevelData
self.army = coder.decodeObjectForKey("army") as? ArmyData
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(GameData.sharedInstance.currentScene, forKey: "currentScene")
coder.encodeObject(GameData.sharedInstance.levelData, forKey: "levelData")
coder.encodeObject(GameData.sharedInstance.army, forKey: "army")
}
/// Loading and saving
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
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 {
return data
}
}
return nil
}
func save() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {
// 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)
})
}
}
@veeneck
Copy link
Author

veeneck commented Apr 2, 2015

Note that army and level data are both classes that implement NSCoding.

@InfiniteAlpha
Copy link

Hi, would you please show the code for the army and leveldata classes? Thanks!

Copy link

ghost commented Oct 26, 2015

Hi there,

I have an error while creating plist file for the first time:
NSBundle.mainBundle().pathForResource("DefaultFile", ofType: "plist")

It seems DefaultFile do not exist...

Copy link

ghost commented Oct 26, 2015

OK, found where the problem lie:
You must create a plist file in your Xcode project.

@covmon1
Copy link

covmon1 commented Jun 24, 2016

What should we include in that plist file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment