1

I'm trying to save the highscore of my game. I'm trying to do this via NSUserDefaults. This is the code I'm using:

//To save highest score
var highestScore:Int = 20
NSUserDefaults.standardUserDefaults().setObject(highestScore, forKey:"HighestScore")
NSUserDefaults.standardUserDefaults().synchronize()

//To get the saved score
var savedScore: Int = NSUserDefaults.standardUserDefaults().objectForKey("HighestScore") as Int
println(savedScore)

But I get an error with NSUserDefaults saying "Expected declaration" and I can't figure out how to properly implement this. Or should I be using NSArchiver for this? And if that is the case how could I implement this?

Rob Bajorek
  • 6,382
  • 7
  • 44
  • 51
Raul Gonzalez
  • 875
  • 1
  • 10
  • 23
  • Side note: NSUserDefaults stores your data in a plist, which can easily be changed by a user hoping to boost their score. Personally, I have successfully given myself unlimited tokens in a few apps. Try to find a better way to store this data. – erdekhayser Sep 23 '14 at 02:01

1 Answers1

3

Use NSCoding. Create a Swift file "HighScore"

import Foundation

class HighScore: NSObject {

    var highScore: Int = 0

    func encodeWithCoder(aCoder: NSCoder!) {
           aCoder.encodeInteger(highScore, forKey: "highScore")
    }

    init(coder aDecoder: NSCoder!) {
        highScore = aDecoder.decodeIntegerForKey("highScore")
    }

    override init() {
    }
}

class SaveHighScore:NSObject {

    var documentDirectories:NSArray = []
    var documentDirectory:String = ""
    var path:String = ""

    func ArchiveHighScore(#highScore: HighScore) {
        documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        documentDirectory = documentDirectories.objectAtIndex(0) as String
        path = documentDirectory.stringByAppendingPathComponent("highScore.archive")

        if NSKeyedArchiver.archiveRootObject(highScore, toFile: path) {
            println("Success writing to file!")
        } else {
            println("Unable to write to file!")
        }
    }

    func RetrieveHighScore() -> NSObject {
        var dataToRetrieve = HighScore()
        documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        documentDirectory = documentDirectories.objectAtIndex(0) as String
        path = documentDirectory.stringByAppendingPathComponent("highScore.archive")
        if let dataToRetrieve2 = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? HighScore {
            dataToRetrieve = dataToRetrieve2
        }
        return(dataToRetrieve)
    }
}

Then for your ViewController:

   import UIKit


    class ViewController: UIViewController, UITextFieldDelegate {
        var Score = HighScore()

        override func viewDidLoad() {
            super.viewDidLoad()

        Score.highScore = 100
        SaveHighScore().ArchiveHighScore(highScore: Score)
        var retrievedHighScore = SaveHighScore().RetrieveHighScore() as HighScore
        println(retrievedHighScore.highScore)

        }
    }
Steve Rosenberg
  • 19,348
  • 7
  • 46
  • 53
  • Hi I implemented the code but I have a problem using the RetrivedHighScore function. Because the return type is a NSObject i'm not able to compare with any int type variable. How do you manage the data for comparing with Ints. For example how to know if the current score is higher than the saved score that would ne the dataToRetrive variable? – Raul Gonzalez Sep 23 '14 at 06:49
  • You have to access your highScore as: retrievedHighScore.highScore. The way I did. The call to the RetrieveHighScore function is an NSObject, but you can access the highScore integer by the . nomenclature. I can rewrite the code to store the integer without the Object call, but the current more complicated way gives you a function you can add other things to. Later for any project where you want to store more than just one variable and types other than just integers can be buried in an NSObject. – Steve Rosenberg Sep 23 '14 at 11:36
  • Sorry to keep bugging you, What do you mean access the integer by the . nomenclature? I'm trying to figure out what this means but can't find any information. Could you give me an example? Sorry but I'm new to swift – Raul Gonzalez Sep 23 '14 at 18:11
  • I've got it. thank you for your help. I now understand ho to handle the class. – Raul Gonzalez Sep 23 '14 at 18:34
  • Hello Steve. Sorry to necro this post, but when I try to use "retrievedHighScore.highScore" in another file, for example if I want to change it in another scene (or file), it claims that there is no member with the name retrievedHighScore. I thought I would be able to continue using this variable in other places but it is not quite working. – TerranceW Jun 23 '15 at 18:50