Нативное API от Apple

Что нового в StoreKit 2

Apple пересмотрела логику покупок и переписала StoreKit. Буду много хвалить - крутой апдейт этого года.

Introducing StoreKit 2
Имя Автора
Автор Воробей Иван iOS разработчик. Пишу библиотеки, веду телеграм-канал.

Сложность первой версии StoreKit была настолько запредельной, что породила огромное количество SAS-решений разной степени паршивости и качества. Ты точно знаешь парочку, и скорее всего не умеешь работать с нативным StoreKit. Это нормально. Я тоже не умею.

Новый StoreKit выглядит как глоток холодной воды в пустыне. Давайте погружаться.

Introducing StoreKit 2

Что нового

Заменили модели, представляющие покупки и операции над ними. Теперь названия без префиксов SK, и в целом интуитивно понятно какие данные репрезентуют модели. Останавливаться на каждом не будем, картинка cо списком:

StoreKit 2 Modes

Запрос продуктов и покупка

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

Теперь круче:

// Получение продуктов
let storeProducts = try await Product.request(with: identifiers)

// Покупка
let result = try await product.purchase()
switch result {
case .success(let verification):
    // handle success
    return result
case .userCancelled, .pending:
    // handle if needed
default: break

Зацените статусы обработки результата. К покупке можно крепить свои данные:

let result = try await product.purchase(options:[.appAccountToken(yourAppToken))])

Для связаности между аккаунтами и аналитики чумовая штука.

Подписки

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

static func isEligibleForIntroOffer(for groupID: String) async -> Bool

Добавили состояние автообновления подписки, которое раньше было доступно только в чеке:

- subscribed - подписка активна
- expired - подписка истекла
- inBillingRetryPeriod - была ошибка при попытке оплаты
- inGracePeriod - отсрочка платежа по подписке. Если grace period у вашей подписки включен и произошла ошибка при оплате, то у пользователя будет ещё какое-то время, пока подписка работает, хотя оплаты ещё не было. Количество дней отсрочки может быть от 6 до 16 в зависимости от длительности самой подписки.
- revoked - доступ ко всем подпискам этой группы отклонён AppStore.

Subscription information

Объект Renewal Info содержит информацию об автообновлением подписки. Например:

- willAutoRenew - флаг, который подскажет, будет ли подписка автопродлена. Если нет, то с какой-то долей вероятности пользователь не планирует дальше использовать подписку в вашем приложении. Самое время подумать о том, как его удержать.
- autoRenewPreference - ID подписки, на которую произойдет автообновление. Например, вы можете проверить, что пользователь сделал downgrade и планирует пользоваться более дешевой версией вашей подписки. В таком случае при желании можете попробовать предложить ему скидку и удержать его на более премиальной версии.
- expirationReason - а здесь вы можете более подробно посмотреть причины истечения срока подписки.

Плюшек еще больше. Восстанавливаться покупки будут автоматически, поддержка async, нормальное API с неймингом функций и моделей, статус подписок, доступность оффера. Выглядит как начало смерти SAS-решений (там всё сложнее, но апдейт всё таки киллер).

Обратная совместимость

Покупки из первой версии будут работать во второй. Новый StoreKit доступен только с iOS 15. Большинство проектов зачем-то держат поддержку iOS 6, так что реальное использование увидим только в инди-проектах.

Спасибо автору статьи, почитайте - там подробнее и на русском. За помощью обращайтесь в наш чатик.