Достижения iOS в автономном игровом центре

Попытка выяснить лучший способ работы с достижениями в Game Center в случае автономного режима (например, включен режим полета).

Насколько я понимаю, Game Center в iOS 5+ заботится о представленных в автономном режиме достижениях и результатах. Он действует как прокси-кеш и отправляет их в онлайн-центр игр при следующем подключении пользователя. Учитывая это, вот что я делаю:

При успешной аутентификации пользователя я загружаю достижения и сохраняю их в словаре.

[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];       
}];

позже, когда я отправляю новое достижение, я проверяю достижения в словаре и не отправляю их, если достижение уже выполнено. Если я отправляю достижение, я также добавляю его в achievments словарь (в памяти), чтобы сразу же подтвердить, что это достижение уже отправлено.

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);
         }
     }];
}

этот подход позволяет мне инициировать отправку в коде игры, не думая, что я отправлю достижение дважды или покажу баннер с уведомлением дважды.

Все работает нормально, когда Game Center онлайн. Но в случае, если я не в сети, у меня есть 2 проблемы.

  1. Загрузка кода возвращает ошибку и исходный словарь achievments не заполнен уже выполненными достижениями, это означает, что каждый раз, когда пользователь запускает игру, он / она снова получает баннер с уведомлением о каждом достижении, даже если оно уже получено. Затем после того, как он помещен в словарь, он не отображается, но я не хочу показывать достижения хотя бы один раз при каждом запуске игры.

  2. Я не уверен, попадут ли достижения в автономном режиме в Game Center, когда пользователь выйдет в сеть. Я могу решить проблему № 1, используя постоянное хранилище (например, базу данных) для хранения статуса достижений между запусками игры, но я должен повторно отправить их, когда Game Center подключен к сети и как определить, действительно ли Game Center подключен к сети, поскольку даже в автономном режиме reportAchievementWithCompletionHandler завершается без ошибок, поэтому я не могу определить, не было ли оно отправлено. Вот как я тестирую, я включаю режим полета, разблокирую несколько достижений, а затем выключаю режим полета, достижения не попадают в Game Center, хотя это может быть проблемой "песочницы".

1 ответ

Решение

Добавьте постоянное хранилище для "разблокированного достижения", о котором вы упомянули, а также сохраните флаг "успешно отправлено в Game Center" для каждого достижения. Затем, когда в Интернете, проверьте результаты loadAchievementsWithCompletionHandler при запуске и периодически, чтобы увидеть, если каждое достижение, которое unlocked && !submitted фактически достиг Game Center и повторно, если нет.

Другие вопросы по тегам