Компания
49,25
рейтинг
10 февраля 2012 в 15:35

Разное → Интеграция iCloud на примере игры Cut the Rope

Привет хабра-житель. Сегодня я хотел бы поведать тебе о своем опыте интеграции iCloud в игру Cut the Rope.

На этот пост меня вдохновил отзыв одного пользователя, пришедший на почтовый адрес технической поддержки:
«I do not need any help, I just wanted to ask you something… How did you
run iCloud Cut the Rope even if it is not a universal application? I
alternate with iPhone and iPad without problems, and it is extraordinary.
Unfortunately, no other developer does this, it is only with universal
applications, so I wonder… you are a magician you or others are not
willing to do anything? You are number one for me, thank you for your
beautiful game and support it for long. Hello».

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

Что такое iCloud?
iCloud это бесплатный облачный сервис, для хранения данных, с поддержкой push-технологий. Создан компанией Apple. В iOS появился, начиная с пятой версии. А в Mac OS начиная с версии 10.7 (Lion).

Проблемы дизайна
Мы хотели, чтобы использование iCloud для пользователя было максимально прозрачным. Поэтому по умолчанию, мы отключили эту функцию и сделали специальный пункт в меню для ее включения:

Так же это сделано для того, чтобы каждый член семьи мог независимо пройти все коробки на своем iOS устройстве, использующем один и тот же Apple ID.

Поскольку обновление данных происходит асинхронно, мы решили добавить следующее уведомление о наличии сохранения в iCloud:


Это уведомление позволяет легко и просто использовать уже существующий в iCloud прогресс. Показывается оно только один раз, после первой синхронизации. Причем синхронизация происходит независимо от настройки в меню. Настройка влияет лишь на то, применяем ли мы полученный прогресс к локальному.

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

В игре Cut the Rope есть возможность сброса игрового прогресса. И мы задумались, стоит ли сбрасывать прогресс, сохраненный в iCloud вместе с ним. Решили, что не стоит. Мы подумали, что в iCloud всегда будет храниться последний и лучший результат по каждому уровню, чтобы пользователь в любой момент смог его восстановить, несмотря ни на какие внешние факторы. В случае, если игрок захочет сбросить прогресс и пройти всю игру с нуля, он может выключить синхронизацию с iCloud.

Интеграция
Есть два пути интеграции iCloud в iOS приложение:

iCloud document storage (сохранение файлов в iCloud аккаунт пользователя) и
iCloud key-value data storage (сохранение данных типа ключ-значение).

Я расскажу о втором варианте, потому что в нашей игре игровой прогресс сохраняется именно таким образом — парой уровень-результат.
  1. Прежде всего, нужно включить поддержку iCloud в приложении на сайте developer.apple.com и перегенирировать соответствующие профили.
  2. Включить entitlements в проекте. 
В xcode версии 4.2 это делается следующим образом:
    
В Project navigator дважды кликаем по проекту, выбираем требуемый target и на вкладке Summary в разделе Entitlements включаем чекбокс напротив строчки “Enable Entitlements”.
  3. В поле iCloud Key-Value Store указать идентификатор контейнера, используемый в приложении. Этот идентификатор может быть одинаковым для разных приложений. Именно таким образом и реализована возможность использования одного прогресса для двух разных приложений. В итоге, для наших приложений идентификатор будет выглядеть как «com.zeptolab.ctr», для полных версий (iPhone и iPad). И «com.zeptolab.ctrlite», для бесплатных версий. В нашем случае пришлось разделить файлы прогресса, потому что в бесплатных версиях другое количество и порядок уровней.
    Вот так выглядят правильные настройки в нашем проекте:

  4. В коде приложения добавить прослушивание сообщений об изменении данных, например так:
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notification:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:[NSUbiquitousKeyValueStore defaultStore]];
    
И не забыть отписаться от этих сообщений, когда они перестанут быть нужны:
    
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
    object:[NSUbiquitousKeyValueStore defaultStore]];
  5. Соответственно в методе
    -(void)notification:(NSNotification *)notification
    обработать ситуацию получения новых данных.
  6. Работа с NSUbiquitousKeyValueStore на примере словаря.
 Доступ к словарю осуществляется следующим образом:
    
NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore];
    NSDictionary* storedDict = [store dictionaryForKey:GAME_PROGRESS];
    А так его можно синхронизировать:

    NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore];
    [store setDictionary:dict forKey:GAME_PROGRESS];
    [store synchronize];

Примечание

Интерфейс NSUbiquitousKeyValueStore очень похож на NSUserDefaults. Но второй нельзя полностью заменить первым. В приложении всегда должен быть локально сохранен актуальный игровой прогресс.

Поддержка старых прошивок:
Поскольку iCloud появился только начиная с iOS 5, то для совместимости с более ранними версиями этот функционал придется отключить.
Делается это следующим образом:
  • Ставим weak link на Foundation.framework, иначе при запуске на старых прошивках столкнемся с такой ошибкой:
    «dyld: Symbol not found: _OBJC_CLASS_$_NSUbiquitousKeyValueStore».
  • И добавляем проверку в коде на доступность iCloud функционала, например так:
    +(BOOL)isCloudAvailable

    {
    
 id class = NSClassFromString(@"NSUbiquitousKeyValueStore");
    
 return class != nil;

    }

    
И изолируем остальной код с её помощью.

Спасибо за внимание. Надеюсь, кто-то найдет эту статью интересной.

Полезные ссылки
iCloud Programming Guide
NSUbiquitousKeyValueStore Class Reference

Автор: @zHolo
ZeptoLab
рейтинг 49,25

Комментарии (18)

  • 0
    Спасибо, очень вовремя!
    При прочтении статьи habrahabr.ru/blogs/macosxdev/137711/ тоже возник вопрос, как два разных приложения пользуются общим iCloud — думал, что идентификатор, в вашем случае это «com.zeptolab.ctr», уникален для приложения. До этого предполагал, что доступ к «своей» папке приложение получает автоматически, а чужие для него закрыты. В то же время, на Маке папки открыты для всех — стало удобно, кстати, закидывать документы на iOS-устройства с мака: просто копируешь вордовский файлик в iCloud-папку «com.apple.pages», и через пару секунд он появляется на айпэде и айфоне. К тому же, iCloud-папки работают на маке как DropBox — помещённое в папку на одном компьютере сразу (ну, после загрузки в облако и скачивания) появляется на других ПК использующих тот же AppleID.
  • +2
    А насколько безопасно хранить так данные об игровом процессе? Не может ли юзер, например, с джейлбрейкнутым девайсом исправить плисты, чтобы «пройти» какой-то уровень или даже всю коробку? Есть у вас защита от этого?
    • +1
      Разве смысл проходить игры заключается в финальной сцене только? Я всегда думал что смысл в самом процессе прохождения.
      • 0
        Да, смысл в этом, но не для всех. Ситуации разные бывают. Кто-то пройти не может уровень и коробка следующая не открывается, а очень хочется. Это для примера.
        • +2
          Какая разница от этого разработчикам?
          • 0
            Так может сразу все уровни открыть? Какая ведь разница, да?
            • 0
              Уровни сначала надо купить.
              • –1
                В Cut the Rope вроде такого нет.
                • 0
                  Ну тогда я не знаю что вам противопоставить.
                  • 0
                    Да не надо мне ничего противопоставлять. Я задал свой вопрос, потому что увидел гипотетическую брешь в механизме получения доступа к новым наборам уровней, созданном в Cut the Rope. И решил узнать у авторов, что они по этому поводу предприняли. Всё. Я тут не спорю.
                    • 0
                      А еще можно методом реверс-инжениринга разобрать как хранит CTR прогресс локально.
                      • 0
                        Если хотите больше знать о причине моего вопроса, то можно прочитать вот эту статью: iCloud позволяет синхронизировать любые файлы
                        Я глубоко в тему iCloud не вникал, но получается, что этот plist, в котором хранится прогресс, может запросто оказаться не только на мобильном девайсе пользователя, но и на его компьютере, где уже не понадобится никакой джейл брейк.
                        А поскольку данная статья есть практически HowTo, то, наверное, стоит задуматься над безопасностью хранения таким образом данных.
                        • 0
                          А ведь начиналось все с игры…
                • 0
                  Хоть с недавних пор в игре можно открыть уровни за деньги, этот способ не является приоритетным и единственным. Пользователь может не тратить деньги и получать доступ к коробкам за звездочки, которые как раз можно по идее получить нечестным способом через гипотетический взлом через iCloud. Убыток налицо.
  • +1
    Если пользователь так хочет получить доступ ко всем уровням, что готов сделать jailbreak, залезть на файловую систему и править plist'ы, то мы ему не мешаем =) Каждый волен получать (или ломать) удовольствие от игры по своему. Единственное мы препятствуем сабмиту таких результатов в Crystal и Game Center, чтобы не мешать другим игрокам.
    • 0
      Извиняюсь, не туда ответил.
      • +2
        Спасибо. Понятно. Довольно либеральный подход.
  • 0
    Почему же вы ещё не в Steam?
    В стиме на хитовой «инди»-игре можно снять неплохую кассу, учитывая, что на старте новые казуальные аркады\головоломки там стоят около 10$, а в сторах ваше приложение, если не ошибаюсь, стоит около 2$. Она уже взорвала всем мозг на мобильных платформах, не вижу причин, по которым CtR не будет иметь успеха в Steam.
    Мне дико понравилась игра, я перепрохожу в свободную минуту «ie»-версию по несколько раз в день, но мне в повседневной жизни совершенно не нужна таблетка, и сейчас мне реально хочется купить iPad ради одной только вашей игры, и только последние капли рационализма в мозгу останавливают от покупки девайса за 700$~ для того, чтобы поиграть в игру за 2$. А ещё меня смутило, что на айпаде все всегда играют, держа айпад в вертикальном положении, очень бы хотелось «широкоформатную» версию(как в ие на html5) на ПК. Подумайте, а.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное