How to Make High Score of Game to Be Saved on Leaderboard, with Swift

How to make High Score of game to be saved on Leaderboard, with Swift?

Well I see a couple things that can contribute to the issue. First is this method...

func loadHighscore() {
let defaults = NSUserDefaults.standardUserDefaults()

let highscoreLabel = childNodeWithName("highscoreLabel") as! PointsLabel
highscoreLabel.setTo(defaults.integerForKey("highscore"))
}

I don't see anywhere you are setting that so pulling it out won't help much. I added the saving to defaults in the saveHighscore: function bellow.

Second is...

saveHighscore(scoreManager.score)

scoreManager.increment() //<-- Here

showLeader()

You should increment before you save your score.

I would try adding these logs to see if this helps...

func saveHighscore(score:Int) {

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(score, forKey: "highscore")
defaults.synchronize()

//check if user is signed in
if GKLocalPlayer.localPlayer().authenticated {

println("authenticated")

let scoreReporter = GKScore(leaderboardIdentifier: "Leaderboard_01")
println("ScoreReporter: \(scoreReporter)")

scoreReporter.value = Int64(score)

let scoreArray: [GKScore] = [scoreReporter]

GKScore.reportScores(scoreArray, withCompletionHandler: {error -> Void in
if error != nil {
print("error")
}
else{
println("reported correctly")
}
})
}
}

Hopefully what does or don't print out in the logs plus actually saving your defaults will help. Good luck.

Edit

So it appears the root of the problem is that you have scoreManager (which is a PointsLabel) in your VC but you also have one that is in your Scene. The one in your scene you are updating the score and life is good. When you hit the button you are actually getting the score from the label in your VC that isn't getting updated. So what you really need is to get to that label in your scene to pull out the score.

So the easiest way I can think of getting it to work properly with as little changes to your code is this…

Remove this line completely…

var scoreManager = PointsLabel(num: 0)

and change your action to this...

@IBAction func leaderboard(sender: UIButton) {

let skView = self.view as! SKView
let scene = skView.scene
let scoreManager = scene.childNodeWithName("pointsLabel") as! PointsLabel

saveHighscore(scoreManager.score)

showLeader()

}

Hopefully that fixes everything =)

Swift 3 Game Center Leaderboard does not save the value of the score

I hope you have properly configured leaderboard at https://itunesconnect.apple.com

Please refer below screen


Sample Image


Also refer below code to save score on leaderboard.

func saveScoreOnGameCenter()
{
let leaderboardID = 111
let sScore = GKScore(leaderboardIdentifier: leaderboardID)
sScore.value = Int64(10)

GKScore.reportScores([sScore], withCompletionHandler: { (error: NSError?) -> Void in
if error != nil {
print(error!.localizedDescription)
} else {
print("Score submitted")

}
})
}

Hope this helps you to figure out problem.

How to get the user's score from leaderboard? - Swift

After a lot of work I managed to find!1

Let's start:

The way it works when accessing the game center is asynchronous, that is, in parallel. To avoid errors and "delays" when receiving and saving information, I recommend saving in UserDefault.
So when you get the data it will be saved in a global variable. You can't just return the value once you get it because it's inside a completionHandler, where the return is Void.

To access the user information you need to access the GKLeaderboard.Entry class where it has the .score method that saves the score that shows on leaderboard. But the only way to access this method is with the standard functions that will return this information when the user is passed by parameter.

.

First step: access the leaderboard with the GKLeaderboard.loadLeaderboards function. In this function, as a parameter:

  • List with the id of the leaderboards that will be accessed

In addition to the completionHandler which will return two instances:

  • A list of leaderboards
  • Variable for error handling (Error)
class func loadLeaderboards(
IDs leaderboardIDs: [String]?,
completionHandler: @escaping ([GKLeaderboard]?, Error?) -> Void
)

.

Second step: access leaderboard data. For this we will use the GKLeaderboard.loadEntries method. In it we will pass as a parameter:

  • A list of users we will access
  • In which period of the leaderboard it will be accessed

In addition to the completionHandler which will return two instances:

  • The .Entry class of the local user (is exactly what i want)
  • A list with the .Entry class in case of more than one user
  • Variable for error handling (Error)
func loadEntries(
for players: [GKPlayer],
timeScope: GKLeaderboard.TimeScope,
completionHandler: @escaping (GKLeaderboard.Entry?,[GKLeaderboard.Entry]?, Error?) -> Void
)

.

So, mixing the two classes, the function to get the user's score in a given leaderboard is:

// Function that takes information and saves it to UserDefault
func getHighScoreFromLeadboard() ->Void {
// Check if the user is authenticated
if (GKLocalPlayer.local.isAuthenticated) {
// Load the leaderboards that will be accessed
GKLeaderboard.loadLeaderboards(
IDs: ["idLeaderboard"] // Leaderboards'id that will be accessed
) { leaderboards, _ in // completionHandler 01: .loadLeaderboards

// Access the first leaderboard
leaderboards?[0].loadEntries(
for: [GKLocalPlayer.local], // User who will be accessed within the leaderboard, in this case the local user
timeScope: .allTime) // Choose which period of the leaderboard you will access (all time, weekly, daily...)
{ player, _, _ in // completionHandler 02: .loadEntries

// Save on UserDefault
UserDefaults.standard.set(player?.score, forKey: "score")
}
}
}
}

Posting score to Game Center leaderboards

First you have to create the GKScore object. Then you set the gkScore.value. Finally, you report the score.

// if player is logged in to GC, then report the score
if GKLocalPlayer.localPlayer().authenticated {
let gkScore = GKScore(leaderboardIdentifier: "leaderBoardID")
gkScore.value = score
GKScore.reportScores([gkScore], withCompletionHandler: ( { (error: NSError!) -> Void in
if (error != nil) {
// handle error
println("Error: " + error.localizedDescription);
} else {
println("Score reported: \(gkScore.value)")
}
}))
}

GameCenter scores are not being posted to the leaderboard

I had the same problem - submitting scores to Game Center by using a new GameKit API available from iOS 14 was never actually saved on the Game Center side (even though there was no any error reported).

Solution which worked for me in the end was simply using a Type Method (with my leaderboardID):

class func submitScore(_ score: Int, 
context: Int,
player: GKPlayer,
leaderboardIDs: [String],
completionHandler: @escaping (Error?) -> Void)

instead of the Instance Method counterpart (which apparently has some bug on Apple side):

func submitScore(_ score: Int, 
context: Int,
player: GKPlayer,
completionHandler: @escaping (Error?) -> Void)

I was going crazy over this, so I hope this helps someone else.

Saving a highscore for Game Center in Swift 2

According to the prerelease documentation, the method signature has changed to be:

class func reportScores(_ scores: [GKScore],
withCompletionHandler completionHandler: ((NSError?) -> Void)?)

This differs from the old documentation which stated:

class func reportScores(_ scores: [AnyObject]!,
withCompletionHandler completionHandler: ((NSError!) -> Void)!)

Note the change to an optional NSError parameter as well as making the entire handler optional.

So you'll have to change your code to not have the explicit error: NSError! as your completion block parameter.



Related Topics



Leave a reply



Submit