Offline Game Center iOS Achievements

Trying to figure out the best way to work with achievements in Game Center in case of offline mode (for example, airplane mode is on).

As far as I understand, Game Center in iOS 5+ takes care of offline submitted achievements and points. It acts as a proxy cache and sends them to the Online Game Center the next time the user is online. Given this, here is what I do:

Upon successful user authentication, I download the results and save them in the dictionary.

[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *gcAchievments, NSError *error) { if (error) { ..skipped ..} //This dictionary will store current achievments, so that we didn't submit them //once more and didn't show notification. achievments = [[NSMutableDictionary alloc] initWithCapacity:gcAchievments.count]; //Storing achievments in dictionary for(GKAchievement *a in gcAchievments) [achievments setObject:a forKey:a.identifier]; }]; 

later when I post a new achievement . I check the achievements in the dictionary and do not send if the achievement is already completed. If I submit an achievement, I will also add it to the achievments dictionary (in memory) to immediately confirm that this achievement has already been sent.

 GKAchievement *cachedAchievment = [achievments objectForKey:identifier]; if (cachedAchievment && cachedAchievment.percentComplete >= 100) { //Already unlocked this achievment. return; } GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier: identifier]; if (achievement) { achievement.percentComplete = percent; [achievement reportAchievementWithCompletionHandler:^(NSError *error) { if (!error) { //Flagging achievment as completed locally to avoid achieving it second time and showing notification. [achievments setObject:achievement forKey:achievement.identifier]; //Now shoing notification banner. GKAchievementDescription * desc = [achievmentsDescriptions objectForKey:achievement.identifier]; [[GKAchievementHandler defaultHandler] notifyAchievement:desc]; } else { NSLog(@"Error in reporting achievements: %@", error); } }]; } 

this approach allows me to initiate a feed in the game code without hesitation that I will send the results twice or show the notification banner twice.

Everyting works great when Game Center is online. But in case I am offline, I have 2 questions.

  • Downloading the code returns an error, and the initial dictionary of achievments not filled with achievements already completed, which means that every time the user starts the game, he receives a notification banner for each achievement again, even if he already received, Then after he is placed in dictionary, it is not displayed, but I do not want to show achievements even once for each game.

  • I’m not sure that achievements sent offline will go to Game Center when the user is online. I can solve problem # 1 by using persistent storage (like a database) to maintain the achievement status between game launches, but I have to resend them when Game Center is online and how to determine if Game Center is really in network, because even the offline reportAchievementWithCompletionHandler completes without errors, so I can’t determine if it was sent. This is how I test, I turned on flight mode, unlocked several achievements, and then turned off flight mode, achievements do not get into Game Center, although this can be a sandbox problem.

+8
ios objective-c game-center achievements
source share
1 answer

Add persistent storage for the “unlock achievement” that you mentioned, and also keep the “successfully sent to Game Center” flag for each achievement. Then, when online, check the results from loadAchievementsWithCompletionHandler at startup and periodically to see if each achievement that is unlocked && !submitted , Game Center has reached and resend if not.

+4
source share

All Articles