Когда вы первый раз сталкиваетесь с In-App Purchase, возникает мысль, засевшая из Конан Дойля “Это же элементарно, Ватсон!” Тем более, что Apple предоставил огромный объем документации, призванной помочь разработчикам сделать все правильно и в максимально короткие сроки.

Так почему же простое добавление In-App Purchase  в проект создает массу головной боли и заставляет нас применять “непереводимую игру слов с использованием местных диалектов и выражений” к компании Apple?

Потому что определенно что-то пойдет не так, и когда это случится, вы окажетесь в полной заднице. Apple предоставляет огромнейший объем документации, но они не предоставляют правильную документацию. Нигде нет пошаговой инструкции как заставить In-App Purchase работать. Нигде нет контрольного списка, если ваша интеграция со StoreKit не работает. Нигде нет описания объекта NSError, которое объяснит вам, почему именно ваш  productID is invalid.

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

Тратить тонну времени на это просто смешно. Чтобы сэкономить вам тысячи нервных клеток я решил написать это пост,  где я подробно описал каждый шаг, который необходимо осуществить, чтобы заставить In-App Purchase работать в вашем проекте. Это очень детально и очень длинно, но, в отличие документации Apple, здесь содержится пошаговая инструкция – шаг за шагом – необходимая любому разработчику для успешного внедрения In-App Purchase.

Итак, давайте приступим.

Обзор In-App Purchase

Ок, друзья, вот секрет, который позволит заставить In-App Purchase работать: разбейте весь процесс на 2 required процесса и 1 optional:

  1. Создать и получить product description
  2. Купить продукт
  3. Скачать продукт (optional)

Что такое “product description” и зачем он нужен? Очень просто. Это как в обычном магазине. Вы подходите к прилавку, берете продукт и показываете его на кассе кассиру, чтобы тот пробил его на кассе. Так же и здесь. Чтобы после нажатия на кнопку “купить” менеджер покупки знал, что именно для вас нужно купить, вы должны дать ему product description или product ID.

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

 Создаем и извлекаем Product Description

Вот очень грубое описание каждого шага, необходимого для создания нового продукта и извлечения его description:

  1. Создать уникальный App ID
  2. Сгенерировать и установить новый provisioning profile
  3. Обновить bundle ID и code signing profile в Xcode
  4. Засабмитить ваше приложение в iTunes Connect, если вы этого еще не сделали
  5. Добавить новый In-App продукт к вашему приложению в iTunes Connect
  6. Написать код для получения product description
  7. Убедиться, что ваш код успешно получает product description
  8. Написать код для осуществления покупки
  9. Написать код для загрузки контента

А сейчас внимание:

  • Вам не нужно сабмитить приложение в AppStore, чтобы работал In-App Purchase
  • Вам не нужно иметь тестовый SandBox аккаунт, чтобы извлечь product description
  • Продукт должен иметь желтый статус “Ready  for Submit”

1. Создаем уникальный App ID

Речь идет о создании Application ID – это ID для приложения, в котором мы будем имплементировать In-App Purchase.

Для этого идем на developer.apple.com в раздел Certificates, Identifiers & Profiles

In-App Purchase

Далее выбираем App IDs в разделе Identifiers и жмем плюсик в правом верхнем углу. Мы попадаем в раздел создания нового App ID. В App ID Description указываем название нашего продукта – это просто название как FaceBook или WhatsApp. Указываем Excplicit App ID.

In-App Purchase

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

In-App Purchase

Далее убеждаемся, что в опциях отмечен  In-App Purchase

In-App Purchase

Жмем Продолжить. И на следующем экране подтверждаем создание нового App ID.

In-App Purchase

 2. Генерируем и устанавливаем новый Provisioning Profile

Для этого там же на developer.apple.com в разделе Certificates, Identifiers & Profiles только теперь выбираем All в разделе Provisioning Profiles и жмем плюсик в правом верхнем углу. Мы попадаем в раздел создания нового Provisioning Profile.

In-App Purchase

Дальше все очень просто. Выбираем наш App ID, выбираем Developer Team, выбираем Devices, придумываем Имя, генерируем, загружаем, кликаем и устанавливаем его в Xcode.

In-App Purchase

Не буду подробно скриншотить данный процесс, т.к. это все таки пост про In-App Purchase, а не про то как создавать Provisioning Profiles.

 3. Обновляем Xcode Settings

После того, как вы создали App ID и Provisioning Profile необходимо сделать ряд апдейтов в проекте в Xcode.

Устанавливаем Bundle (без Prefix! только ID!)

In-App Purchase

In-App Purchase

И убедитесь, что раздел Code Signing вкладки Build Settings для вашего Active Target выглядит так.

In-App Purchase

 4. Добавляем приложение в iTunes Connect

Если ваше приложение уже в AppStore, вы можете пропустить этот шаг. В противном случае идем в iTunes Connect

iTunes Connect

Выбираем  My App, далее жмем плюсик и выбираем New App. Заполняем всю необходимую информацию.

iTunes Connect

Жмем Create и после всего этого мы наконец-то можем добавить наш In-App Product

5. Добавляем новый In-App Product к вашему приложению в iTunes Connect

Идем в раздел Features

iTunes Connect

После чего мы попадаем в In-App Purchase где жмем плюсик.

iTunes Connect

Далее вам нужно выбрать тип продукта – Consumable, Non-Consumable, Automatically Renewable Subscriptions, Free Subscription, Non-Renewing Subscription.

Что это значит? Очень просто.

Consumable – это то, что один покупатель может покупать много раз! Например золото в играх или жизни!

Non-Consumable – это то, что один покупатель может купить только один раз! Например Pro опция в программе или электронный журнал и т.д.!

Все остальное подписки – бесплатная, возобновляемая, невозобновляемая.

Далее надо заполнить информацию о продукте:

  • Reference Name: Собственно это имя продукта. Например Pro Upgrade или Magazine 12
  • Product ID: уникальный ID вашего продукта. Обычно если App ID com.myCompany.myApp, то Product ID это com.myCompany.myApp.proUpgrade.
  • Price Tier: Ценовой Тир. Посмотрите матрицу цен. Это просто.
  • Cleared for Sale: Отметьте это сразу. Если вы не сделаете это, вы будете получать invalid product ID во время тестирования.
  • Language to Add: выберите язык – для тестирования достаточно одного
  • Screenshot: добавляем скриншот – это может быть обложка журнала или копия экрана, показывающая как ваш In-App Product работает. Проще говоря, эта картинка должна объяснить сотрудникам Apple, которые будут аппрувить ваш продукт, – что вы, собственно продаете.

Все. Если вы предполагаете закачивать какой-нибудь контент после осуществления покупки, и предполагаете хранить его на серверах Apple, вы должны загрузить его сразу. Используйте Application Loader для этого.

Добавленный продукт должен иметь статус “Ready for Submit”

6. Пишем код для получения product description

Теперь мы наконец можем приступить к написанию кода для извлечения product ID. Для этого нам понадобится StoreKit Framework

Внимание! StoreKit не работает на Симуляторе

  1. Добавляем StoreKit framework к нашему проекту.
  2. Добавляем указатель на SKProduct в нашем .h файле:
InAppPurchaseManager – это синглтон.

  1. Для запроса данных о продукте, вызываем requestProUpgradeProductData и реализуем метод делегата SKProductsRequestDelegate

При запросе информации о продукте нужно использовать полный Product ID как например @”com.myCompany.myAwesomeApp.myProductID”

7. Убеждаемся, что ваш код успешно получает product description

А теперь наступил момент истины. Если вы все сделали правильно, то после выполнения запроса, вызовется productRequest:didReceiveResponse: и вы получите 1 response.product и 0 response.invalidIdentifiers.

Если что-то не так, то вам прийдет 1 response.invalidIdentifiers

In-App Purchase

Если вам пришел response.invalidIdentifier, приготовьтесь, потому что StoreKit API не предложит вам помощь и не скажет почему именно он инвалид! Мило, не правда ли!?

Еще один момент. SKProduct class предложит вам локализированную версию названия и описания вашего продукта, но не цены. Чтобы справиться с этим упущением, вот категория, предоставляющая локализированную цену:

 Что делать, если вы получили inavlid product ID  в response.invalididentifiers

Поблема в том, что StoreKit не скажет вам почему именно это произошло, нет кода ошибки, ничего нет. Вам просто нужно еще раз все перепроверить, и убедиться, что вы все сделали правильно.

Вот контрольный чек-лист:

  • Вы включили опцию In-App Purchases для вашего App ID?
  • Вы отметили Cleared for Sale для вашего продукта?
  • Ваш project’s .plist Bundle ID совпадает с вашим App ID?
  • Вы сгенерировали и усановили Provisioning Profile для вашего App ID?
  • Вы настроили ваш проект для того, чтобы code sign использовал provisioning profile?
  • Вы используете полный product ID когда вы вызываете SKProductRequest?
  • Вы подождали некоторое время после того как добавили ваш продукт в iTunes Connect?
  • Вы заполнили все банковские реквзиты и приняли все соглашения в iTunes Connect?
  • Вы пробовали удалить ваше приложение с устройства и переустановить его заново?
  • Ваше устройство не джейлбрекнутое?

Если вы ответили “нет” на несколько вопросов, у вас проблема.

Если вы ответили “да” на все вопросы и у вас все равно invalid product ID, то у вас проблема, которую я не встречал ранее.

Существует мнение, что если вы получаете invalid product ID и вы считаете, что все сделали правильно, – то должно пройти время с момента того, как мы добавили свой продукт в iTunes Connect. Сколько времени? Люди писали до 24 часов. Имейте это в виду.

Если вы успешно извлекли продукт, я вас поздравляю. В следующей части поговорим о том, как осуществить покупку. И в завершении – как скачать контент с серверов Apple.

Продолжение следует…

In-App Purchase: Полное руководство #2