How to save a highscore to a game in swift with UserDefaults?
Try this
func saveHighScore() {
UserDefaults.standard.set(score, forKey: "HIGHSCORE")
}
Saving highscore with NSUserDefaults
In the code you gave, you are setting "Highscore" when updating, but are attempting to get the value for "HighScore" (Notice the capital S)
This line:
if (highScoreDefault.valueForKey("HighScore") != nil){
Change it to:
if (highScoreDefault.valueForKey("Highscore") != nil){
Nsuserdefaults highscore saving
Change viewDidLoad to:
override func viewDidLoad() {
super.viewDidLoad()
if let hscore = defaults.valueForKey("highscore") {
highscore = hscore
highScoreResult.text = String(hscore)
}
}
That should load the highscore from the defaults once you're app launches.
Saving highscores with NSUserDefaults
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)
}
}
save a highscore with UserDefaults in Swift 3
You still haven't clearly explained what problem you're seeing, but my guess is that your high score doesn't appear to be saved across restarts of the app.
The problem is that you initialize fastestScore
to 100000000000000.0 when your ThirdViewController
is created. You don't load it from UserDefaults
. Thus even if there is a stored fastestScore
, you don't load it at launch.
You should fix this with two changes. First, in your application delegate, you should register a default high score:
let bestScoreKey = "bestScore"
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, willFinishLaunchingWithOptions options: [UIApplicationLaunchOptionsKey : Any]?) -> Bool {
UserDefaults.standard.register(defaults: [
bestScoreKey: 1_000_000_000.0
])
return true
}
}
You should also register any other default settings there.
Second, in ThirdViewController
, you should initialize fastestScore
from UserDefaults
. You can also save changes back to UserDefaults
in the property's didSet
observer:
var fastestScore: Double = UserDefaults.standard.double(forKey: bestScoreKey) {
didSet {
UserDefaults.standard.set(fastestScore, forKey: bestScoreKey)
}
}
Other tips:
There is no reason to make
fastestScore
aFloat
if your scores areDouble
. Just save it as aDouble
.Don't repeat string keys. The compiler won't catch your spelling errors. Put the key in a constant like I did with
bestScoreKey
.You can use
_
in long numbers to make them more readable.Insulting your player is a questionable marketing strategy. How would you have felt if the first comment on your question was “Seriously? Are you even trying?”
Related Topics
Uiview Hide/Show with Animation
Multiple Uilabels Inside a Self Sizing Uitableviewcell
How to Use Avfoundation to Crop a Video
Real Time Blur Effect for Navigation Bar
Swift with iOS 5 Deployment Target
How to Present iOS Uiactionsheet in Swift
iPhone App Under Test Crashes After a Few Days
Auto-Renewable Subscription in iOS7
Where to Store Global Constants in an iOS Application
Get an Array of Property Values from an Object Array
How to Underline a Uilabel in Swift
How to Access Coredata Model in Today Extension (Ios)
Change Text of "Return" Keyboard Button
Type 'Viewcontroller' Does Not Conform to Protocol 'Uitableviewdatasource'
Getting Device Orientation in Swift
Swift - How Creating Custom Viewforheaderinsection, Using a Xib File