Search code examples
swiftgame-centergame-center-leaderboard

Retrieve Best Score Game Center Swift


I'm in trouble, I can't fix a bug related to the func for retrieve the best score from the Game Center. The function is working good if you have a score but it's crashing if the user doesn't have score.

Any suggestions? Code below:

func retrieveBestScore() {
        if GKLocalPlayer.localPlayer().isAuthenticated {

            // Initialize the leaderboard for the current local player
            var gkLeaderboard = GKLeaderboard(players: [GKLocalPlayer.localPlayer()])
            gkLeaderboard.identifier = leaderboardID
            gkLeaderboard.timeScope = GKLeaderboardTimeScope.allTime

            // Load the scores
            gkLeaderboard.loadScores(completionHandler: { (scores, error) -> Void in

                // Get current score
                var currentScore: Int64 = 0
                if error == nil {
                    if (scores?.count)! > 0 {
                        currentScore = (scores![0] ).value
                        //We also want to show the best score of the user on the main screen
                        if self.language.contains("it"){
                            self.labelBestScore.text = "Miglior Punteggio: " + String(currentScore)
                            self.bestScore = Int(currentScore)
                        }else{
                            self.labelBestScore.text = "Your Best Score: " + String(currentScore)
                            self.bestScore = Int(currentScore)
                        }
                        print("Punteggio attuale",currentScore)
                    }
                }

            })
        }
    }

Thank you!


Solution

  • Based on your code it looks like you may be encountering this issue due to force unwrapping your 'scores' array.

    Try something like this in your closure:

    var currentScore: Int64 = 0
    if error == nil, let scores = scores {
        if scores.count > 0 {
            currentScore = scores[0].value
            //We also want to show the best score of the user on the main screen
            if self.language.contains("it"){
                self.labelBestScore.text = "Miglior Punteggio: " + String(currentScore)
                self.bestScore = Int(currentScore)
            }else{
                self.labelBestScore.text = "Your Best Score: " + String(currentScore)
                self.bestScore = Int(currentScore)
            }
            print("Punteggio attuale",currentScore)
        }
    }
    

    Here's a secondary approach that condenses your code even more, I think this should work as well but it's hard to say for sure without seeing more code, it might need a couple minor changes possibly.

    guard error == nil, let scores = scores, let currentScore = scores.first?.value else {
        print("GameCenter error or no scores: \(String(describing: error)))")
        return
    }
    
    //We also want to show the best score of the user on the main screen
    if self.language.contains("it"){
        self.labelBestScore.text = "Miglior Punteggio: " + String(currentScore)
        self.bestScore = Int(currentScore)
    }else{
        self.labelBestScore.text = "Your Best Score: " + String(currentScore)
        self.bestScore = Int(currentScore)
    }
    print("Punteggio attuale",currentScore)