Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GameKit and Social APIs

GameKit and Social APIs

Vladimir Pouzanov

March 15, 2011
Tweet

More Decks by Vladimir Pouzanov

Other Decks in Programming

Transcript

  1. Game Center и социальные API © 2010-2011 Владимир Пузанов, Hack&Dev

    LLC Разработка приложений для платформы iOS
  2. План занятия ✤ Введение в GameKit API ✤ Функциональные возможности

    Game Center ✤ Таблицы результатов ✤ Достижения ✤ Многопользовательская игра
  3. GameKit API ✤ GameKit предоставляет функции для создания игр с

    возможностью социального взаимодействия ✤ Компоненты GameKit: ✤ Game Center – централизованный сетевой сервис (iOS 4.1) ✤ P2P-соединения – поиск и передача данных между устройствами через Wi-Fi или Bluetooth (iOS 3.0) ✤ Голосовое общение – простой API для голосового общения (iOS 3.0)
  4. Game Center Авторизация Приглашения в игру Поиск игровых сессий P2P

    передача данных Друзья Достижения Таблицы результатов Голосовое общение
  5. Game Center как платформа ✤ Самостоятельное приложение, которое предоставляет доступ

    ко всей социальной информации ✤ Сервис для хранения, передачи, обработки социальных данных и установки сетевых P2P-соединений ✤ Фреймворк, предоставляющий API для доступа к социальным и сетевым функциям
  6. Сервисы Game Center ✤ Авторизация – Game Center предоставляет унифицированный

    механизм для авторизации пользователей, прозрачный для конечного приложения ✤ Таблицы результатов (leaderboards) – публикация рейтинга пользователей ✤ Достижения (achievements) – публикация достижений в игре с поддержкой скрытых достижений и прогресса по конкретным достижениям
  7. Сервисы Game Center ✤ Сетевая игра – автоматический поиск подходящих

    игроков для сетевой игры (с поддержкой работы через серверы Game Center или собственные) ✤ Приглашения на сетевую игру позволяют приглашать друзей поиграть, при этом уведомление проходит через механизм APSN, приложение не обязательно должно быть запущено для получения приглашения ✤ P2P-соединения – API, который предоставляет возможность передавать данные между участниками созданной сетевой игры
  8. Общие принципы и требования ✤ Почти все API Game Center

    требуют авторизированного локального пользователя. Если пользователь не авторизирован (или Game Center недоступен) – отключайте доступ к функциям Game Center. ✤ Приложение должно использовать стек UIViewController (Game Center требует отображения своих контроллеров модально) ✤ Большинство API работает асинхронно через блоки ✤ При проблеме с сетью во время отправки данных сохраняйте их для повторной отправки позже ✤ При проблеме с сетью во время получения данных Game Center может вернуть закешированные данные (вместе с кодом ошибки)
  9. Общие принципы и требования ✤ Game Center должен быть сконфигурирован

    в iTunes Connect ✤ У приложения должен быть указан правильный Bundle ID ✤ Если приложение не может работать без Game Center – необходимо указать это в зависимостях приложения (UIRequiredDeviceCapabilities) ✤ Если приложение может работать частично без Game Center – необходимо использовать слабую линковку и проверять наличие классов Game Center на устройстве и версию iOS >=4.1
  10. Тестирование приложения ✤ Тестировать приложение с Game Center можно только

    при наличии аккаунта в iOS Developer Program, независимо от того, тестируется оно на симуляторе, или устройстве Сборка Целевая аудитория Окружение Game Center Симулятор Разработчик Песочница Устройство (Debug) Разработчик Песочница Устройство (Ad-Hoc) Тестер Песочница Устройство (AppStore) Пользователи Основные серверы
  11. Работа с пользователями ✤ Пользователь должен создать учетную запись в

    Game Center ✤ Данные таблиц результатов и достижений автоматически сохраняются для текущего пользователя ✤ У каждого пользователя свой уникальный список друзей ✤ Пользователь идентифицируется по playerID и alias: ✤ playerID – уникальная строка, определяющая пользователя ✤ alias – псевдоним пользователя, подходящий для отображения
  12. Авторизация локального пользователя - (void)authenticateLocalPlayer { ! [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError

    *error) { ! ! if(!error) { ! ! ! // обработка данных пользователя ! ! } else { ! ! ! // сообщение об ошибке, блокирование доступа к Game Center ! ! } ! }]; } ✤ Авторизация должна быть выполнена как можно раньше (в didFinishLaunchingWithOptions:) ✤ В случае недоступности локального пользователя любой доступ к функциям Game Center должен быть заблокирован
  13. Деавторизация локального пользователя ✤ Локальный пользователь может быть деавторизирован во

    время жизни приложения (используя функции многозадачности iOS) ✤ В таком случае необходимо заблокировать доступ к Game Center и предложить повторную авторизацию [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(authenticationChanged) name:GKPlayerAuthenticationDidChangeNotificationName object:nil]; ... - (void)authenticationChanged { ! if([GKLocalPlayer localPlayer].isAuthenticated) { ! ! // локальный пользователь потенциально изменился } else { ! ! // локальный пользователь недоступен ! } }
  14. - (void)retrieveFriends { ! if ([GKLocalPlayer localPlayer].authenticated) { ! !

    [[GKLocalPlayer localPlayer] loadFriendsWithCompletionHandler:^(NSArray *friends, NSError *error) { ! ! ! if(!error) { ! ! ! ! // обработка списка друзей – playerID массиве friends ! ! ! } else { ! ! ! ! // обработка ошибки ! ! ! } ! ! }]; ! } } Список друзей ✤ Список друзей не загружен по умолчанию, для его получения необходимо выполнить запрос
  15. - (void)loadPlayerData:(NSArray *)identifiers { ! [GKPlayer ! loadPlayersForIdentifiers:identifiers ! withCompletionHandler:^(NSArray

    *players, NSError *error) { ! ! if(!error) { ! ! ! // обработка массива объектов GKPlayer ! ! } else { ! ! ! // обработка ошибки ! ! } ! }]; } Список друзей ✤ Для получений объектов GKPlayer на базе списка идентификаторов необходимо выполнить еще один запрос
  16. Таблицы результатов ✤ Таблицы результатов отображают «успеваемость» пользователей по какому-то

    критерию (набранные очки, заработанные деньги и т.д.) ✤ Параметры таблиц: ✤ Единицы измерения ✤ Порядок сортировки (по возрастанию или убыванию) ✤ Форматирование значений ✤ Вывод в общей таблице, или отдельные таблицы в зависимости от режима игры
  17. Настройка таблицы результатов в iTunes Connect ✤ Leaderboard Reference Name

    – информационное имя для таблицы ✤ Leaderboard ID – уникальный идентификатор ✤ Score Format Type: ✤ Integer – 123456789 ✤ Fixed Point – To 1/2/3 Decimal(s) – 12345678.9 ✤ Elapsed Time – To the Minute (second, 1/100 second) – 123:45 ✤ Money – Whole Numbers – 123456789 ✤ Money – To 2 Decimals – 1234567,89
  18. - (void)reportScore:(int64_t)score forCategory:(NSString *)category { ! GKScore *scoreReporter = [[[GKScore

    alloc] initWithCategory:category] autorelease]; ! scoreReporter.value = score; ! [scoreReporter reportScoreWithCompletionHandler:^(NSError *error) { ! ! if(error) { ! ! ! // сохранение scoreReporter для повторной попытки ! ! } ! }]; } Отправка результата ✤ Результат сохраняется в объекте класса GKScore как значение int64_t (64-битное целое со знаком) ✤ В случае проблемы при отправке, объект GKScore должен быть сохранен (например с помощью протокола NSCoding) для повторной попытки отправки позднее
  19. Отображение стандартного контроллера ✤ Для отображения таблицы результатов можно использовать

    стандартный контроллер GKLeaderboardViewController ✤ Настраиваемые свойства: ✤ category – идентификатор категории (заданный в iTunes Connect) ✤ timeScope – период отображения результатов (за день, неделю, все время)
  20. - (void)showLeaderboard { ! GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init]

    autorelease]; ! if(leaderboardController) { ! ! leaderboardController.leaderboardDelegate = self; ! ! // инициализация category, timeScope ! ! [self presentModalViewController:leaderboardController animated:YES]; ! } } - (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController { ! // сохранение category, timeScope ! [self dismissModalViewControllerAnimated:YES]; } Отображение стандартного контроллера ✤ При возможности, сохраняйте значения category и timeScope при выходе из контроллера и восстанавливайте их при последующем запуске
  21. Получение данных из таблиц результатов ✤ В случае, если необходимо

    отобразить собственный интерфейс для таблицы результатов, Game Center API предоставляет возможность получения массива объектов GKScore по заданным критериям: ✤ playerScope – все игроки или только друзья ✤ range – диапазон возвращаемых объектов ✤ category и timeScope – аналогично, как и для стандартного контроллера ✤ Также, можно сделать запрос по конкретным идентификаторам игроков с помощью метода initWithPlayerIDs:
  22. - (void)retrieveTopTenScores { ! GKLeaderboard *leaderboardRequest = [[[GKLeaderboard alloc] init]

    autorelease]; ! if(leaderboardRequest) { ! ! leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal; ! ! leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime; ! ! leaderboardRequest.range = NSMakeRange(1,10); ! ! [leaderboardRequest ! ! loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) { ! ! ! if(error) { ! ! ! ! // обработка ошибки ! ! ! } ! ! ! if(scores) { ! ! ! ! // обработка списка результатов ! ! ! } ! ! }]; ! } } Получение данных из таблиц результатов ✤ Массив scores может быть возвращен даже при наличии ошибки (на базе закешированных данных)
  23. - (void)loadCategoryTitles { ! [GKLeaderboard loadCategoriesWithCompletionHandler:^( ! NSArray *categories, NSArray

    *titles, NSError *error) { ! ! if(error) { ! ! ! // обработка ошибки ! ! } ! ! if(categories) { ! ! ! // обработка ID категорий и их заголовков ! ! } ! }]; } Получение данных из таблиц результатов ✤ Не используйте свой код форматирования вместо score.formattedValue, иначе данные будут выглядеть по-разному в приложении и в Game Center ✤ Для использования данных локализации необходимо получать данные из iTunes Connect
  24. Достижения ✤ Цели для игроков ✤ Мотивация для прохождения разных

    режимов игры на разных уровнях сложности ✤ Параметры достижений: ✤ Название достижения ✤ Описание, отображаемое пока достижение не получено ✤ Описание, отображаемое когда достижение получено ✤ Изображение (отображается только у полученых достижений) ✤ «Стоимость» достижения (до 1000 баллов на приложение) ✤ Изначальное отображение достижения
  25. Обновление состояния достижения ✤ Состояние достижения – значение от 0.0

    до 100.0 ✤ Если достижение было создано как скрытое по умолчанию – оно отображается (даже при изменении состояния в 0.0) ✤ Понизить состояние нельзя ✤ При достижении значения 100.0 достижение отмечается как полученное
  26. - (void)reportAchievementIdentifier:(NSString *)identifier percentComplete:(float) percent { ! GKAchievement *achievement =

    [[[GKAchievement alloc] initWithIdentifier:identifier] autorelease]; ! if(achievement) { ! ! achievement.percentComplete = percent; ! ! [achievement reportAchievementWithCompletionHandler:^(NSError *error) { ! ! ! if(error) { ! ! ! ! // сохранение achievement для повторной попытки ! ! ! } ! ! }]; ! } } Обновление состояния достижения ✤ Аналогично как и с GKScore, при проблемах с сетью объект GKAchievement необходимо сохранить и отправить еще раз позже
  27. - (void)loadAchievements { ! [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) {

    ! ! if(error) { ! ! ! // обработка ошибки ! ! } ! ! if(achievements) { ! ! ! // обработка списка достижений ! ! } ! }]; } Обновление состояния достижения ✤ Обновлять таким образом необходимо только новые достижения, список текущих достижений необходимо получить как можно раньше (сразу после авторизации)
  28. - (void)resetAchievements { ! [GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error) { ! !

    if(error) { ! ! ! // обработка ошибки ! ! } ! }]; } Сброс списка достижений ✤ При необходимости, список достижений можно сбросить ✤ Все скрытые по умолчанию достижения снова станут скрытыми
  29. - (void)showAchievements { ! GKAchievementViewController *achievements = [[[GKAchievementViewController alloc] init]

    autorelease]; ! if(achievements) { ! ! achievements.achievementDelegate = self; ! ! [self presentModalViewController:achievements animated:YES]; ! } } - (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController { ! [self dismissModalViewControllerAnimated:YES]; } Отображение стандартного контроллера ✤ Контроллер списка достижений не содержит опций для настройки отображения
  30. - (void)retrieveAchievmentMetadata { ! [GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:^(NSArray *descriptions, NSError *error) {

    ! ! if(error) { ! ! ! // обработка ошибки ! ! } ! ! if(descriptions) { ! ! ! // обработка списка объектов GKAchievementDescription ! ! } ! }]; } Отображение собственного контроллера ✤ Информацию по достижению (описание) необходимо запрашивать отдельно
  31. [achievementDescription loadImageWithCompletionHandler:^(UIImage *image, NSError *error) { ! if(error) { !

    ! // обработка ошибки ! } }]; Отображение собственного контроллера ✤ Так же отдельно запрашиваются изображения полученных достижений
  32. Сетевая игра ✤ Стандартный интерфейс поиска матча ✤ Входящие приглашения

    ✤ Програмные средства поиска матчей ✤ Поддержка до четырех участников (до 16 с использованием своего сервера)
  33. Использование платформы Game Center для передачи данных ✤ API предоставляет

    функции для передачи данных по надежному и по быстрому каналам ✤ Рекомендуемые размеры пакетов: ✤ До 87Кб при использовании надежного транспорта ✤ До 1000Кб при использовании ненадежного транспорта
  34. Использование своего сервера ✤ GKMatch предоставляет только идентификаторы участников ✤

    Абсолютно вся передача данных должна быть реализована самостоятельно