Game Center- handling failed achievement submissions?

纵然是瞬间 提交于 2019-12-04 18:44:55

You could add the GKAchievement objects that fail to register to an array and then resend them when you get back connectivity. You should also consider committing that array to persistent storage, in case your app terminates before it has a chance to send those achievements. Try this in your completion handler:

// Load or create array of leftover achievements
if (achievementsToReport == nil) {
    achievementsToReport = [[NSKeyedUnarchiver unarchiveObjectWithFile:pathForFile(kAchievementsToReportFilename)] retain];
    if (achievementsToReport == nil) {
        achievementsToReport = [[NSMutableArray array] retain];
    }
}

@synchronized(achievementsToReport) {
    if(error == nil)
    {
        // Achievement reporting succeded

        // Resend any leftover achievements
        BOOL leftoverAchievementReported = NO;
        while ([achievementsToReport count] != 0) {
            [self resendAchievement:[achievementsToReport lastObject]];
            [achievementsToReport removeLastObject];
            leftoverAchievementReported = YES;
        }

        // Commit leftover achievements to persistent storage
        if (leftoverAchievementReported == YES) {
            [NSKeyedArchiver archiveRootObject:achievementsToReport toFile:pathForFile(kAchievementsToReportFilename)];
        }
    }
    else
    {
        // Achievement reporting failed
        [achievementsToReport addObject:theAchievement];
        [NSKeyedArchiver archiveRootObject:achievementsToReport toFile:pathForFile(kAchievementsToReportFilename)];
    }
}

Hope this helps.

M Katz

I see that the two answers here focus on the specific mechanisms for archiving the undelivered achievement messages. For a higher-level description of the overall approach, you can see my answer to this related question: Robust Game Center Achievement code

Achievements (and all of the gamecenter stuff like leaderboard updates) conform to NSCoding. You can store them if you get an error submitting them and submit them later. This is what apple recommends in their docs.

Your application must handle errors when it fails to report progress to Game Center. For example, the device may not have had a network when you attempted to report the progress. The proper way for your application to handle network errors is to retain the achievement object (possibly adding it to an array). Then, your application needs to periodically attempt to report the progress until it is successfully reported. The GKAchievement class supports the NSCoding protocol to allow your application to archive an achievement object when it moves into the background.

from: http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/GameKit_Guide/Achievements/Achievements.html#//apple_ref/doc/uid/TP40008304-CH7-SW13

    // Submit an achievement to the server and store if submission fails
- (void)submitAchievement:(GKAchievement *)achievement 
{
    if (achievement)
    {
        // Submit the achievement. 
        [achievement reportAchievementWithCompletionHandler: ^(NSError *error)
        {
            if (error)
            {
                // Store achievement to be submitted at a later time. 
                [self storeAchievement:achievement];
            }
            else
            {
                 NSLog(@"Achievement %@ Submitted..",achievement);
                if ([storedAchievements objectForKey:achievement.identifier]) {
                    // Achievement is reported, remove from store.
                    [storedAchievements removeObjectForKey:achievement.identifier];
                } 
                [self resubmitStoredAchievements];
            }
        }];
    }
}

In case anyone stumbles upon this question in the future, Apple now has sample code for submitting achievements that includes a way to archive achievements that failed to submit (due to no network connection, etc). You'll find it in the Game Center programming guide.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!