Управление сообщениями App Store в iOS SDK
App Store иногда должен показывать пользователям сообщения о подписке: запросить согласие на повышение цены, сообщить о проблемах с оплатой или представить win-back offer. По умолчанию StoreKit показывает эти сообщения самостоятельно, пока открыто приложение — даже поверх пейвола, онбординга или оформления заказа.
Чтобы выбирать момент показа самостоятельно, переключите Adapty SDK в режим ручной обработки сообщений. Тогда SDK добавляет каждое сообщение в список ожидающих, а приложение показывает этот список при вызове showStoreMessages.
В ручном режиме StoreKit не показывает сообщения самостоятельно. Если ваше приложение никогда не вызывает showStoreMessages, пользователи никогда не увидят запрос на согласие с изменением цены или уведомление о проблеме с оплатой.
Перед началом
Вам потребуется:
- Adapty iOS SDK версии 4.2 или выше: в более ранних версиях отсутствует API сообщений стора.
- iOS 16 или Mac Catalyst 16 или выше: StoreKit не доставляет сообщения приложениям на более ранних версиях, поэтому API сообщений стора помечен как доступный начиная с iOS 16. На macOS этот API недоступен.
SDK Adapty поддерживает iOS 15. Если ваше приложение тоже поддерживает iOS 15, оберните каждый вызов store messages в if #available(iOS 16.0, *) или пометьте тип, делающий этот вызов, аннотацией @available(iOS 16.0, *). Без одной из этих проверок приложение не скомпилируется. Примеры в этой статье включают такие проверки. Если ваш deployment target — iOS 16 или выше, их можно опустить.
Включение ручной обработки
Чтобы перехватывать сообщения App Store, установите значение storeMessagesHandling равным .manual при активации SDK:
let configurationBuilder = AdaptyConfiguration
.builder(withAPIKey: "YOUR_PUBLIC_SDK_KEY")
.with(storeMessagesHandling: .manual) // .auto is the default
SDK начинает перехватывать сообщения в момент активации и хранит их в памяти в течение текущей сессии приложения. При значении по умолчанию .auto SDK ничего не перехватывает, а getPendingStoreMessageTypes и showStoreMessages ничего не делают.
Получение типов ожидающих сообщений
Чтобы узнать, есть ли ожидающие сообщения, вызовите getPendingStoreMessageTypes. Метод возвращает типы ожидающих сообщений, не показывая и не удаляя их:
if #available(iOS 16.0, *) {
let pendingTypes = await Adapty.getPendingStoreMessageTypes()
if pendingTypes.contains(.billingIssue) {
// For example, skip the upsell and show the billing message first
}
}
Каждое сообщение относится к одному из следующих типов:
| Тип | Сообщение |
|---|---|
.generic | Общее сообщение App Store. |
.priceIncreaseConsent | Запрос на согласие с повышением цены подписки. |
.billingIssue | Уведомление о проблеме с оплатой подписки. Доступно на iOS 16.4 и выше. |
.winBackOffer | Подходящий win-back offer. Доступно на iOS 18 и выше. |
Тип сообщения, который SDK не распознаёт, имеет значение storekit_<number>.
Показ ожидающих сообщений
Когда ваше приложение достигает точки, в которой системное окно не прервёт пользователя — например, после того как пользователь закрыл флоу или завершил онбординг — вызовите showStoreMessages:
SDK показывает сообщения одно за другим. После того как StoreKit отображает сообщение, SDK удаляет его из списка ожидания. Если StoreKit не может показать сообщение, SDK записывает ошибку в лог Adapty, сохраняет сообщение для следующего вызова и продолжает обработку остальных сообщений.
Показывать только определённые типы сообщений
Чтобы показывать только часть ожидающих сообщений, передайте нужные типы в for. Остальные сообщения останутся в очереди:
try await Adapty.showStoreMessages(
for: [.billingIssue, .priceIncreaseConsent],
using: displayStoreKitMessage
)
Без for SDK показывает все ожидающие сообщения, включая типы, которые он не распознаёт.
Ошибки
showStoreMessages выбрасывает AdaptyError с одним из следующих кодов:
| Код | Название | Причина |
|---|---|---|
| 3201 | operationInProgress | Другой вызов showStoreMessages всё ещё отображает сообщения. Дождитесь его завершения и повторите попытку. |
| 3202 | resolverFailure | Только UIKit: вы не передали сцену, и SDK не нашёл ни одной активной сцены на переднем плане. Вызовите метод снова, когда приложение находится на переднем плане, или передайте сцену явно. |
| 9000 | operationInterrupted | Задача, вызвавшая метод, была отменена. |