Game Center Leaderboard scores delayed and wrong time - ios

I'm currently testing various sandbox accounts for Game Center. I only use leaderboards from Game Center in my app. If I get a new high score, that new scores doesn't appear as soon as I go to look at leaderboards, it appears a few seconds and sometimes minutes later.
How do I get the scores to appear as soon as I received those high scores? Also, I just tested the game and received a new high score minutes ago yet leaderboards states i received this new score 3 hours ago. How do I fix that as well?
GKScore *scoreReporter = [[GKScore alloc]initWithLeaderboardIdentifier:#"identifier"];
scoreReporter.value = HighScoreNumber;
[GKScore reportScores:#[scoreReporter] withCompletionHandler:^(NSError *error) {
if (error != nil) {
}
else
{
}
}];

Related

google Play game Leaderboard in ios

I have used Google play game leaderboard in my iOS app.i am submitting score from my and fetch score from there. i am using following method to submit score
`[score submitScoreWithCompletionHandler: ^(GPGScoreReport *report, NSError *error) {
if (error) {
// Handle the error
} else {
// Analyze the report, if you'd like
}
}];`
and below code to present leaderboard
NSString *targetLeaderboardId = #"my id";
[[GPGLauncherController sharedInstance] presentLeaderboardWithLeaderboardId:targetLeaderboardId];
but fetching score takes to much time.is there any way to reload or refresh leaderboard data.
anyone have any idea!
Unfortunately, Google Play Games Services for iOS has been deprecated, so I would not recommend putting too much time into it. More information: https://android-developers.googleblog.com/2017/04/focusing-our-google-play-games-services.html

Game Center Group Leaderboard issue

I have an iOS game with one Game Center leaderboard. Recently I published the game and it works fine with no issues. Then I did light version of the game and I'd like to use the same leaderboard for both games. I combined both versions of the game into the Game Center group and modified leaderboard ID, because Apple requires to start group leaderboard names with grp..
Now, if I load scores I receive nil. But if I firstly submit some score and load after that I receive only score for the local player. I checked the leaderboard on itunesconnect and I know for sure that there are a lot of records in the leaderboard. The leaderboard is the same as it was before combining into the group. I thought that Game Center needs some time to update, but I've waited about one day still see no changing.
So my question is why I received nil or score only for local player? Do I do something wrong? Or this is just a Game Center bug?
I found some similar issues here but the most recent one was posted about two years ago. Does anyone have any ideas? Any help appreciated!
Here is my code to load scores:
func loadScores(){
let leaderboard = GKLeaderboard()
leaderboard.identifier = "grp.myLeaderboardID"
leaderboard.loadScores { (scores, error) in
if error != nil {
print(error!.localizedDescription)
} else {
//do something with the scores
}
}
}
}
and to sumbit scores:
func submitScore(value: Int64) {
let leaderboardID = "grp.myLeaderboardID"
let sRating = GKScore(leaderboardIdentifier: leaderboardID)
sRating.value = value
GKScore.report([sRating], withCompletionHandler: { (error: Error?) -> Void in
if error != nil {
print(error!.localizedDescription)
}
})
}
UPDATE.
The problem has gone suddenly. I think that the issue has been dealt with apple server bug but with combining into a group

Game Center leaderboard score request's completion handler is never called for players that have no score

My game implements a custom user interface that lists the local player's friends.
I also have a Game Center leaderboard.
When my game lists the players, it also tries to load their scores from the leaderboard, using this code:
GKLeaderboard *request = [[GKLeaderboard alloc] initWithPlayerIDs:myFriends];
request.timeScope = GKLeaderboardTimeScopeAllTime;
request.identifier = #"my_leaderboards";
if (request != nil) {
[request loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (error != nil) {
NSLog(#"Error: %#",error.localizedDescription);
}
if (scores != nil) {
NSLog(#"WORKED: %#",scores);
}
}];
}
And it works just fine.
... except when one of the friends has no score (for instance, they never played the game in the first place). When one of the players in myFriends has no score entry in the leaderboard, the completion handler is never called. There is no error and no score reported, because it never fires in the first place.
I realised this when testing an account that has two friends. One friend has played the game (so they have a score), and the other has not. The completion handler never got called. Then, I unfriended the guy that had no score, and the completion handler worked fine, returning the score of the friend that did have a score.
I somewhat understand this behaviour - after all, I'm asking it to give me a score that does not exist. But is there a workaround? As in, tell it to return a 0 if there is no score?
iOS 7.
It cannot be helped, the completion handler indeed won't be called because there is no score entry in the leaderboards. Although I still don't understand why doesn't it just return an error saying so.
Since the custom friend list just shows statistics, I just put a loading icon in place for each statistic. If the handler is not called for more than 10 seconds, I assume that there is no score entry and just display a 0.

reset a single gamecenter achievement

In my app I have an achievement for 10 wins in a row. So when the user wins 5 games in a row I report the achievement 50% completed - this works fine. When the user loses some games I call my resetAchievment method which sets the percentage to 0 and reports the percentage again. However when I restart the app the percentage gets read from the GKAchivement and it still shows 50%.
- ( void ) resetAchievement
{
_gamekitAchievement.percentComplete=0.0f;
_counter = 0;
[self report];
}
- ( void ) report
{
_gamekitAchievement.showsCompletionBanner = YES;
[_gamekitAchievement reportAchievementWithCompletionHandler:^(NSError *error)
{
if (error)
{
NSLog(#"reporting Achievment: %# failed, error: %#", _gamekitAchievement.identifier, [error localizedDescription]);
}
}];
}
Is it not possible to report a smaller percentage again - or am I doing something wrong?
I have no actual experience from GameKit at all but from reading the documentation and searching the web it seems you're only able to report progress and not regression(?) Not to mention the fact that you can only reset ALL achievements... Perhaps the following would still help you achieve (ahem) what you want:
Update all your local achievement data with + (void)loadAchievementsWithCompletionHandler:
Store this data in the userDefaults for safety
Do NOT reset the local achievement data
Reset all the achievements with + (void)resetAchievementsWithCompletionHandler:
Change the percentComplete to 0 on the achievement in question.
report progress of all the achievements from your local storage
Now, as I mention, having no hands-on experience with this framework the above might not be practical for a number of reasons I am unaware of (the way progress is presented to the player for instance). Guess it was worth a shot to share the idea anyways...
Short answer: It is not possible to report a smaller percentage again.
Long answer: A lower GameCenter score will not overwrite a higher one.
For example you have a high score of 10 points and it's recorded in GameCenter.
If in the next try you get 5 points and they are submitted to GC, your high score of 10 won't be affected.
Similarly if you try to 'reset' your score, it counts as submitting a new score of 0, so it won't make a difference.
This only applies to scores and achievements submitted to GameCenter, inside your app you can do anything you want (for example your own custom leaderboard or something)
If you think about it, 5 wins is not 50% of the way there, since they could lose the 6th, then win 10 in a row, in which case they played 16 total games and 5 wins was more like 30% of the way there. In this case, it is all or nothing, so don't report anything until they have all 10.
Please be aware that storing the progress towards an achievement in NSUserDefaults doesn't take different GameCenter users into account. That means, if Player A (logged into GameCenter) makes some progress and at 90 % progress another Player B on the same device logs into GameCenter with his own account, he starts with the progress made by Player A.
You might solve this by storing a whole NSDictionary with the Player IDs as keys into NSUserDefaults.
What you'll want to do is save it NSUserdefaults. then, Call the NSUser default and check what number it is by using an IF statement.
-(void)checkAcheivement{
scoreNumber = [NSUserDefaults standardUserDefaults] objectForKey:#"GamesWon"]
if(scoreNumber == 10){
//Run code to save achievement in Game Center(_gamekit stuff)
}
//-(void)checkScoreFire{
//scoreNumber = [NSUserDefaults standardUserDefaults] objectForKey:#"GamesWon"]
//if(scoreNumber == 5){
//Run code to set up alert view for 5 wins below
//UIAlertView* message = [[UIAlertView alloc]
// initWithTitle: #"Alert"
// message: #"You are halfway to the Achievement!"
// delegate: self
// cancelButtonTitle: #"Dismiss"
// [message show];
//}
//to save score use this method:
-(void)saveScore{
scoreNumber = [NSUserDefaults standardUserDefaults] objectForKey:#"GamesWon"]
if(gameScore > scoreNumber){
[[NSUserDefaults standardUserDefaults]setInteger:scoreNumber forKey:#"GamesWon"];
}
This will only post the achievement if it is ten, i suggest not putting the achievement in until then, because it makes it more difficult. I also suggest setting up an AlertView to let the person know they are halfway there. You can do so with the code commented above with the checkScoreFive method. Remember to declare everything in the .h file as well.
IBOutlet UIAlertView *AlertView;
-(void)checkAcheivement;
-(void)checkScoreFire;
-(void)saveScore;
int gameScore;
int scoreNumber;

Posting scores for all GameCenter players

Can you post score in GameCenter for all players at once ? It seems that the API allows only to post for current player. I am trying to implement vote capability allowing current player to vote / score other players in GameCenter.
GKScore* gkScore = [[GKScore alloc] initWithCategory:category];
gkScore.value = score;
// ??? Score for current player ONLY - how to record score for other players ???
[gkScore reportScoreWithCompletionHandler:
^(NSError* error) {
....
BOOL success = (error == nil);
[delegate onScoresSubmitted:success];
}];
You can only post scores for the current player. This is for security purposes.
If multiple people are playing the same game, when they open up their app on their own device, that is when you submit the score.
With iOS 7, this is no longer true. But you can only do so when ending the game, using
endMatchInTurnWithMatchData:scores:achievements:completionHandler:

Resources