HylianGinyu
HylianGinyu

Reputation: 13

Swift 3: How do you save a high score programmatically?

I have a button that increases a score, and if it's the highest score then that number is saved as the high score even after the app is closed and opened again.

That part works fine, but after I reopen the app and click the button my high score gets reset and becomes equal to the score. I think it's because I'm calling my highscore variable when I should be calling my HighscoreDefault, but I don't get how you access that value... if that even is the problem.

How do I keep the high score from changing to values lower than itself after the app is reopened?

import UIKit

class ViewController: UIViewController {

    let phrase = "Your Score: "
    var increasingNum = 0
    let otherphrase = "High Score: "
    var highscore = 0
    var label: UILabel?
    var otherlabel: UILabel?
    let HighscoreDefault = UserDefaults.standard

    override func viewDidLoad() {

        super.viewDidLoad()

        let label = UILabel(frame: CGRect(x: self.view.frame.size.width / 2 - 100, y: 100, width: 200, height: 20))
        label.textAlignment = .center
        label.text = "\(phrase) \(increasingNum)"
        self.view.addSubview(label)
        self.label = label

        let otherlabel = UILabel(frame: CGRect(x: self.view.frame.size.width / 2 - 100, y: 200, width: 200, height: 20))
        otherlabel.textAlignment = .center
        otherlabel.text = "\(otherphrase) \(highscore)"
        self.view.addSubview(otherlabel)
        self.otherlabel = otherlabel

        let button = UIButton(frame: CGRect(x: self.view.frame.size.width / 2 - 150, y: self.view.frame.size.height / 2 - 50, width: 300, height: 100))
        button.backgroundColor = UIColor.cyan
        button.addTarget(self, action: #selector(scoreGoUp), for: .touchUpInside)
        self.view.addSubview(button)

        if let highscore = HighscoreDefault.value(forKey: "highscore") {

            otherlabel.text = "\(otherphrase) \(highscore)"
        }
    }

    func scoreGoUp (sender: UIButton){

        increasingNum += 1
        self.label?.text = "\(phrase) \(increasingNum)"
        if (increasingNum > highscore){

            highscore = increasingNum
            self.otherlabel?.text = "\(otherphrase) \(highscore)"
            HighscoreDefault.set(highscore, forKey: "highscore")
        }
    }
}

Upvotes: 0

Views: 1241

Answers (6)

alexburtnik
alexburtnik

Reputation: 7741

In my opinion the most convenient way to save highscore is to implement a computed variable like this:

var highScore: Int {
    get {
        return UserDefaults.standard.integer(forKey: "highScore")
    }
    set {
        UserDefaults.standard.set(newValue, forKey: "highScore")
    }
}

This way you won't bother yourself thinking about UserDefaults after you have that variable in your controller or singleton.

Upvotes: 2

Nick xu
Nick xu

Reputation: 511

init your highscore here:

 if let highscoreLast = HighscoreDefault.value(forKey: "highscore") {

    otherlabel.text = "\(otherphrase) \(highscore)"
    // you should get your highscore here               
    highscore = highscoreLast

    }

Upvotes: 0

Ahmad F
Ahmad F

Reputation: 31645

highscore default value is 0, so for each first time the action called if (increasingNum > highscore) should be always true. What do you need to do someWhere in your code to assign your HighscoreDefault.value(forKey: "highscore") as? Int to highscore:

override func viewDidLoad() {

    super.viewDidLoad()

    let label = UILabel(frame: CGRect(x: self.view.frame.size.width / 2 - 100, y: 100, width: 200, height: 20))
    label.textAlignment = .center
    label.text = "\(phrase) \(increasingNum)"
    self.view.addSubview(label)
    self.label = label

    let otherlabel = UILabel(frame: CGRect(x: self.view.frame.size.width / 2 - 100, y: 200, width: 200, height: 20))
    otherlabel.textAlignment = .center
    otherlabel.text = "\(otherphrase) \(highscore)"
    self.view.addSubview(otherlabel)
    self.otherlabel = otherlabel

    let button = UIButton(frame: CGRect(x: self.view.frame.size.width / 2 - 150, y: self.view.frame.size.height / 2 - 50, width: 300, height: 100))
    button.backgroundColor = UIColor.cyan
    button.addTarget(self, action: #selector(scoreGoUp), for: .touchUpInside)
    self.view.addSubview(button)

    if let highscore = HighscoreDefault.value(forKey: "highscore") as? Int {
        // here is the extra job!!
        self.highscore = highscore
        otherlabel.text = "\(otherphrase) \(highscore)"
    }
}

Hope it helped.

Upvotes: 0

Cruz
Cruz

Reputation: 2632

when you reopen your app, UserDefault's maybe save your highScore but your code didn't assign it to your ViewController's highscore variable

if let highscore = HighscoreDefault.value(forKey: "highscore") as? Int {
        self.highscore = highscore
        otherlabel.text = "\(otherphrase) \(highscore)"
}

Upvotes: 1

Annie Gupta
Annie Gupta

Reputation: 2822

Instead of

if let highscore = HighscoreDefault.value(forKey: "highscore") {

            otherlabel.text = "\(otherphrase) \(highscore)"
        }

Add this line in your code in ViewDidLoad

if let highscore = HighscoreDefault.value(forKey: "highscore") {

        otherlabel.text = "\(otherphrase) \(highscore)"
        self.highscore = highscore as! Int
    }

Upvotes: 1

Nguyen Hoan
Nguyen Hoan

Reputation: 1693

highscore must be a array of int not int
And you should sort this array(ascending or decrease) if new score > the smallest item in the array and array.count > count of your hight core default -> you change this item by new score. And save them
if array.count< just add newscore to array and save

Upvotes: -1

Related Questions