I have followed a great tutorial online on how to use Game Center in your iOS apps. It can be found here: http://code.tutsplus.com/tutorials/ios-sdk-game-center-achievements-and-leaderboards-part-2--mobile-5801
However the code for submitting an achievement seems to unlock achievements which have already been unlocked and I don't understand why. Here is my method which deals with a achievements:
-(void)submitAchievement:(NSString*)identifier percentComplete:(double)percentComplete {
if (self.earnedAchievementCache == NULL) {
[GKAchievement loadAchievementsWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (error == NULL) {
NSMutableDictionary *tempCache = [NSMutableDictionary dictionaryWithCapacity: [scores count]];
for (GKAchievement *score in tempCache) {
[tempCache setObject: score forKey: score.identifier];
}
self.earnedAchievementCache = tempCache;
[self submitAchievement:identifier percentComplete: percentComplete];
}
else {
// Something broke loading the achievement list. Error out, and we'll try again the next time achievements submit.
[self callDelegateOnMainThread: @selector(achievementSubmitted:error:) withArg: NULL error: error];
}
}];
}
else {
// Search the list for the ID we're using...
GKAchievement *achievement = [self.earnedAchievementCache objectForKey:identifier];
if (achievement != NULL) {
if ((achievement.percentComplete >= 100.0) || (achievement.percentComplete >= percentComplete)) {
// Achievement has already been earned so we're done.
achievement = NULL;
}
achievement.percentComplete = percentComplete;
}
else {
achievement = [[[GKAchievement alloc] initWithIdentifier:identifier] autorelease];
achievement.percentComplete = percentComplete;
// Add achievement to achievement cache...
[self.earnedAchievementCache setObject:achievement forKey:achievement.identifier];
}
if (achievement != NULL) {
// Submit the Achievement...
[achievement reportAchievementWithCompletionHandler: ^(NSError *error) {
[self callDelegateOnMainThread:@selector(achievementSubmitted:error:) withArg:achievement error:error];
}];
}
}
}
Thanks for your time, Dan.
Can you try this code and see the log. I added NSLog statements to see if the code detects achievement is completed and sets the achievement to nil. Also delete NULL from the code. Let me know how it works out.
-(void)submitAchievement:(NSString*)identifier percentComplete:(double)percentComplete {
if (!self.earnedAchievementCache) {
[GKAchievement loadAchievementsWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (!error) {
NSMutableDictionary *tempCache = [NSMutableDictionary dictionaryWithCapacity: [scores count]];
for (GKAchievement *score in scores) { // the error is here
[tempCache setObject: score forKey: score.identifier];
}
self.earnedAchievementCache = tempCache;
[self submitAchievement:identifier percentComplete: percentComplete];
}
else {
// Something broke loading the achievement list. Error out, and we'll try again the next time achievements submit.
[self callDelegateOnMainThread: @selector(achievementSubmitted:error:) withArg: NULL error: error];
}
}];
}else {
// Search the list for the ID we're using...
GKAchievement *achievement = [self.earnedAchievementCache objectForKey:identifier];
NSLog(@"achievement %f",achievement.percentComplete);
if (achievement) {
if ((achievement.percentComplete >= 100.0) || (achievement.percentComplete >= percentComplete)) {
NSLog(@"Achievement has already been earned so we're done.");
achievement = nil;
}else{
achievement.percentComplete = percentComplete;
}
}else {
achievement = [[[GKAchievement alloc] initWithIdentifier:identifier] autorelease];
achievement.percentComplete = percentComplete;
// Add achievement to achievement cache...
[self.earnedAchievementCache setObject:achievement forKey:achievement.identifier];
}
if (achievement) {
NSLog(@"Submit the Achievement...");
[achievement reportAchievementWithCompletionHandler: ^(NSError *error) {
[self callDelegateOnMainThread:@selector(achievementSubmitted:error:) withArg:achievement error:error];
}];
}
}
}