This question already has answers here:
Swift - Saving highscore using NSUserDefaults
(5 answers)
Closed 6 years ago.
I am searching for an efficient way to store a "high score" integer in this simple game I am building with Swift in iOS. I want it to keep track of it even if the player shuts down the app, closes it, and restarts it. How should I use the NSUserDefaults function to save this data? Thanks in advance! :)
//TO SAVE INTO USER DEFAULT
NSUserDefaults.standardUserDefaults().setInteger(1234, forKey: "highScore")
//TO RETRIEVE FROM USER DEFAULT
var highScore = NSUserDefaults.standardUserDefaults().integerForKey("highScore")
Save that highscore like this:
let highscore = 20
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setValue(highscore, forKey: "highscore")
userDefaults.synchronize() // it is not necessary
When you want to get the info, you have to "read" the highscore from the dictionary like this:
if let highscore = userDefaults.valueForKey("highscore") {
// do something here when a highscore exists
}
else {
// no highscore exists
}
Related
I'm learning application development working on a quiz game. I'd like to add statistics to the game. For example, the average score since the app has been downloaded. How can I store the scores on the device in order to reuse them after the app has been closed?
You should take a look at UserDefault. It's basically a dictionary that persists until the user uninstalls your app. I like to write a wrapper around it to get strong typing and ease of reference:
struct Preferences {
static func registerDefaults() {
UserDefaults.standard.register(defaults: [kAverageScore: 0])
}
// Define your key as a constant so you don't have to repeat a string literal everywhere
private static let kAverageScore = "averageScore"
static var averageScore: Double {
get { return UserDefaults.standard.double(forKey: kAverageScore) }
set { UserDefaults.standard.set(newValue, forKey: kAverageScore) }
}
}
Here's how to use it: before you call it for the first time in your app, you must register the defaults. These are the values that your app ships with. On iOS, it only really matters for the very first time the user launches your app. On OS X, do this every time your app starts because the user can delete the app's preferences from ~/Library/Application Support.
// You usually do this in viewDidLoad
Preferences.registerDefaults()
From then on, getting and setting the property is easy:
let averageScore = Preferences.averageScore
Preferences.averageScore = 5.5
You should take a look at UserDefaults
Example
let defaults = UserDefaults.standard
defaults.set(25, forKey: "Age")
defaults.set(true, forKey: "UseTouchID")
defaults.set(Double.pi, forKey: "Pi")
To read values back
let age = defaults.integer(forKey: "Age")
let useTouchID = defaults.bool(forKey: "UseTouchID")
let pi = defaults.double(forKey: "Pi")
UserDefaults
I have a spritekit game which I have a highscore in. It uses NSUser Default. But I get the highscore 2, and then I close the app completely, and then open it it shows my highscore 2, and then get one as a score. It remains as 2. However, I close the app again and open it, it shows the highscore 1. Why does it do this? This is my code. Does the if condition not work? Note: This is just narrowed down to Highscore code.
import SpriteKit
//In the DidMoveToView function
if let Highscore1 = defaults.stringForKey("Highscore"){
HighScoreLabel.text = "HIGHSCORE: \(Highscore1)"
}
//In the touches began func
//Making what happens when the User Fails and a new highscore is achieved
if Score > highscore {
defaults.setObject("\(Score)", forKey: "Highscore")
}
Thank you in advance
The issue is you are reading the highscore from NSUserDefaults and showing it in the HighScoreLabel. But you didn't assigned/stored the value in highscore variable, because of that it remains at 0. That makes the following condition true when you open the app and plays for the first time:
if Score > highscore {
defaults.setObject("\(Score)", forKey: "Highscore")
}
You need to change the high score reading part like:
if let Highscore1 = defaults.stringForKey("Highscore") {
HighScoreLabel.text = "HIGHSCORE: \(Highscore1)"
// Storing current high score to variable
highscore = Int(Highscore1)
}
currently I'm working on a game project and I've run into an issue where the game's highscore doesn't update unless I quit the app (completely close) and run the game again. In terms of code I've got this written down.
var data = NSUserDefaults.standardUserDefaults()
//this is when the level is over and the highscore is saved
if score > level1HS{
data.setInteger(score, forKey: "level1HS")
data.synchronize()
}
//and this is in the main menu where the highscore is shown
level1text.text = "\(String(level1HS))"
I've also tried replacing the level1text.text = "\(String(level1HS)" with this level1text.text = "\(level1HS)"
Can somebody please help me find a way to have the game update the highscore as soon as it is achieved ? Thank you!
Wherever you're trying to update the high score, you'll need to listen to the notification for when StandardUserDefaults() gets updated. It would look like this:
let defaults = NSUserDefaults.standardUserDefaults()
let center = NSNotificationCenter.defaultCenter()
center.addObserverForName(NSUserDefaultsDidChangeNotification, object: nil, queue: nil) { (notification) -> Void in
let newScore = defaults.objectForKey("level1HS")
}
Have you tried doing the following?
var level1HS = 10
NSUserDefaults.standardUserDefaults().setObject(highestScore, forKey:"level1HS")
NSUserDefaults.standardUserDefaults().synchronize()
Your problem is probably that you are not using the .synchronize() method.
Also, check out this question:
SpriteKit High Score
I am using NSUserDefaults to display the score from my GameScene on my resetViewController. The problem is that if the user doesn't score it will display the players last score.
In GameScene
var score: Int = 0
var scoreLabel = SKLabelNode()
let defaults = NSUserDefaults.standardUserDefaults()
score++
scoreLabel.text = "\(score)"
defaults.setObject(scoreLabel.text, forKey: "scoring")
In resetViewController
var score = defaults().stringForKey("scoring")
YourScore.text = score
I'm sure it's something simple but I can't seem to figure it out
When you need to score to reset, just call
NSUserDefaults.standardUserDefaults().setObject(nil, forKey: "scoring")
removeObjectForKey: removes the value from NSUserDefaults. You could also set it to zero. Or just not use NSUserDefaults -- there's not much point in using it unless you need to persist the value between restarts of your app.
I suggest saving the integer, not the string. That way the default will be zero, and you can easily reset the score by setting the key to zero.
NSUserdefaults.standardUserDefaults().IntegerForKey("score")
NSUserdefaults.standardUserDefaults().setInteger(0, forKey: "score")
my NSUserDefaults doesn't save my game high score properly. When am playing(testing) the game it works ok but when i quit(terminate) and restart or when i transition from scene to scene my high score goes back to 0. can anyone help me fix this issue? thank in advance.
var score = 6
NSUserDefaults.standardUserDefaults().integerForKey("highscore")
//Check if score is higher than NSUserDefaults stored value and change NSUserDefaults stored value if it's true
if score > NSUserDefaults.standardUserDefaults().integerForKey("highscore") {
NSUserDefaults.standardUserDefaults().setInteger(score, forKey: "highscore")
NSUserDefaults.standardUserDefaults().synchronize()
}
NSUserDefaults.standardUserDefaults().integerForKey("highscore")
The problem is that this statement, which appears twice, does nothing at all:
NSUserDefaults.standardUserDefaults().integerForKey("highscore")
It fetches the "highscore" key's value from user defaults, but immediately throws it away, because you are not assigning the result to anything, like this:
let highscore = NSUserDefaults.standardUserDefaults().integerForKey("highscore")
Thus, even though you are successfully storing the high score in user defaults, you are never retrieving it - so there is no basis for your claim that it is not being saved, because you have given yourself no way of knowing whether or not is has been saved.