Достижения 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 проблемы.
Загрузка кода возвращает ошибку и исходный словарь
achievments
не заполнен уже выполненными достижениями, это означает, что каждый раз, когда пользователь запускает игру, он / она снова получает баннер с уведомлением о каждом достижении, даже если оно уже получено. Затем после того, как он помещен в словарь, он не отображается, но я не хочу показывать достижения хотя бы один раз при каждом запуске игры.Я не уверен, попадут ли достижения в автономном режиме в Game Center, когда пользователь выйдет в сеть. Я могу решить проблему № 1, используя постоянное хранилище (например, базу данных) для хранения статуса достижений между запусками игры, но я должен повторно отправить их, когда Game Center подключен к сети и как определить, действительно ли Game Center подключен к сети, поскольку даже в автономном режиме
reportAchievementWithCompletionHandler
завершается без ошибок, поэтому я не могу определить, не было ли оно отправлено. Вот как я тестирую, я включаю режим полета, разблокирую несколько достижений, а затем выключаю режим полета, достижения не попадают в Game Center, хотя это может быть проблемой "песочницы".
1 ответ
Добавьте постоянное хранилище для "разблокированного достижения", о котором вы упомянули, а также сохраните флаг "успешно отправлено в Game Center" для каждого достижения. Затем, когда в Интернете, проверьте результаты loadAchievementsWithCompletionHandler
при запуске и периодически, чтобы увидеть, если каждое достижение, которое unlocked && !submitted
фактически достиг Game Center и повторно, если нет.