Обработка событий пейвола в iOS SDK
Этот гайд охватывает обработку событий для покупок, восстановлений, выбора продуктов и отображения пейвола. Вам также необходимо реализовать обработку кнопок (закрытие пейвола, открытие ссылок и т. д.). Подробности смотрите в нашем гайде по обработке действий кнопок.
Пейволы, настроенные с помощью Paywall Builder, не требуют дополнительного кода для совершения и восстановления покупок. Тем не менее они генерируют события, на которые ваше приложение может реагировать. К таким событиям относятся нажатия кнопок (кнопки закрытия, ссылки, выбор продуктов и т. д.), а также уведомления о действиях, связанных с покупками на пейволе. Ниже описано, как обрабатывать эти события.
Это руководство предназначено только для новых пейволов Paywall Builder, которые требуют Adapty SDK версии 3.0 или выше.
Хотите увидеть реальный пример интеграции Adapty SDK в мобильное приложение? Посмотрите наши примеры приложений — они демонстрируют полную настройку: отображение пейволов, совершение покупок и другие базовые функции.
Обработка событий в SwiftUI
Чтобы управлять процессами на экране пейвола или отслеживать их, используйте модификатор .paywall в SwiftUI:
@State var paywallPresented = false
var body: some View {
Text("Hello, AdaptyUI!")
.paywall(
isPresented: $paywallPresented,
paywall: paywall,
viewConfiguration: viewConfig,
didPerformAction: { action in
switch action {
case .close:
paywallPresented = false
case let .openURL(url):
// handle opening the URL (incl. for terms and privacy)
default:
// handle other actions
}
},
didSelectProduct: { /* Handle the event */ },
didStartPurchase: { /* Handle the event */ },
didFinishPurchase: { product, info in /* Handle the event */ },
didFailPurchase: { product, error in /* Handle the event */ },
didStartRestore: { /* Handle the event */ },
didFinishRestore: { /* Handle the event */ },
didFailRestore: { /* Handle the event */ },
didFailRendering: { error in
paywallPresented = false
},
didFailLoadingProducts: { error in
return false
}
)
}
Можно регистрировать только те параметры замыканий, которые нужны вашему приложению — неиспользуемые параметры создаваться не будут.
| Параметр | Обязательный | Описание |
|---|---|---|
| isPresented | обязательный | Привязка, управляющая отображением экрана пейвола. |
| paywallConfiguration | обязательный | Объект AdaptyUI.PaywallConfiguration, содержащий визуальные параметры пейвола. Используйте метод AdaptyUI.paywallConfiguration(for:products:viewConfiguration:observerModeResolver:tagResolver:timerResolver:). Подробнее см. в разделе Получение пейволов Paywall Builder и их конфигурации. |
| didFailPurchase | обязательный | Вызывается при ошибке покупки (например, платёж не разрешён, проблемы с сетью, недействительный продукт). Не вызывается при отмене пользователем или ожидающих платежах. |
| didFinishRestore | обязательный | Вызывается при успешном восстановлении покупки. |
| didFailRestore | обязательный | Вызывается при ошибке восстановления покупки. |
| didFailRendering | обязательный | Вызывается при ошибке рендеринга интерфейса. В этом случае обратитесь в поддержку Adapty. |
| fullScreen | необязательный | Определяет, отображается ли пейвол в полноэкранном режиме или как модальное окно. По умолчанию true. |
| didAppear | необязательный | Вызывается, когда экран пейвола появляется на экране. Также вызывается, когда пользователь нажимает кнопку web-пейвола внутри пейвола и web-пейвол открывается во встроенном браузере. |
| didDisappear | необязательный | Вызывается, когда экран пейвола закрывается. Также вызывается, когда web-пейвол, открытый из пейвола во встроенном браузере, исчезает с экрана. |
| didPerformAction | необязательный | Вызывается при нажатии пользователем кнопки. У разных кнопок разные идентификаторы действий. Два идентификатора предопределены: close и openURL, остальные задаются в конструкторе. |
| didSelectProduct | необязательный | Вызывается, если продукт был выбран для покупки — пользователем или системой. |
| didStartPurchase | необязательный | Вызывается, когда пользователь начинает процесс покупки. |
| didFinishPurchase | необязательный | Вызывается при успешном завершении покупки. |
| didFinishWebPaymentNavigation | необязательный | Вызывается после попытки открыть web-пейвол для покупки — успешной или нет. |
| didStartRestore | необязательный | Вызывается, когда пользователь начинает процесс восстановления покупок. |
| didFailLoadingProducts | необязательный | Вызывается при ошибках загрузки продуктов. Верните true, чтобы повторить загрузку. |
| didPartiallyLoadProducts | необязательный | Вызывается, когда продукты загружены частично. |
| showAlertItem | необязательный | Привязка, управляющая отображением элементов оповещения поверх пейвола. |
| showAlertBuilder | необязательный | Функция для рендеринга представления оповещения. |
| placeholderBuilder | необязательный | Функция для рендеринга представления-заглушки, пока пейвол загружается. |
Обработка событий в UIKit
Чтобы управлять процессами на экране пейвола или отслеживать их, реализуйте методы AdaptyPaywallControllerDelegate.
События, инициированные пользователем
Выбор продукта
Если пользователь выбирает продукт для покупки, вызывается этот метод:
func paywallController(
_ controller: AdaptyPaywallController,
didSelectProduct product: AdaptyPaywallProductWithoutDeterminingOffer
) { }
Пример события (нажмите, чтобы развернуть)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}Начало покупки
Если пользователь инициирует процесс покупки, вызывается этот метод:
func paywallController(_ controller: AdaptyPaywallController,
didStartPurchase product: AdaptyPaywallProduct) {
}
Пример события (нажмите, чтобы развернуть)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}Метод не вызывается в режиме Observer mode. Подробнее см. в разделе iOS — Отображение пейволов Paywall Builder в режиме Observer mode.
Начало покупки через web-пейвол
Если пользователь инициирует покупку через web-пейвол, вызывается этот метод:
func paywallController(
_ controller: AdaptyPaywallController,
shouldContinueWebPaymentNavigation product: AdaptyPaywallProduct
) {
}
Пример события (нажмите, чтобы развернуть)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}Успешная или отменённая покупка
Если покупка выполнена успешно, вызывается этот метод:
func paywallController(
_ controller: AdaptyPaywallController,
didFinishPurchase product: AdaptyPaywallProductWithoutDeterminingOffer,
purchaseResult: AdaptyPurchaseResult
) { }
}
Примеры событий (нажмите, чтобы развернуть)
// Successful purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "success",
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
}
}
}
}
// Cancelled purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "cancelled"
}
}В этом случае рекомендуем закрыть экран пейвола.
Метод не вызывается в режиме Observer mode. Подробнее см. в разделе iOS — Отображение пейволов Paywall Builder в режиме Observer mode.
Ошибка покупки
Если покупка завершается с ошибкой, вызывается этот метод. Это включает ошибки StoreKit (ограничения платежей, недействительные продукты, сбои сети), ошибки верификации транзакций и системные ошибки. Обратите внимание: отмена пользователем вызывает didFinishPurchase с результатом cancelled, а ожидающие платежи этот метод не вызывают.
func paywallController(
_ controller: AdaptyPaywallController,
didFailPurchase product: AdaptyPaywallProduct,
error: AdaptyError
) { }
Пример события (нажмите, чтобы развернуть)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "purchase_failed",
"message": "Purchase failed due to insufficient funds",
"details": {
"underlyingError": "Insufficient funds in account"
}
}
}Метод не вызывается в режиме Observer mode. Подробнее см. в разделе iOS — Отображение пейволов Paywall Builder в режиме Observer mode.
Ошибка покупки через web-пейвол
Если Adapty.openWebPaywall() завершается с ошибкой, вызывается этот метод:
func paywallController(
_ controller: AdaptyPaywallController,
didFailWebPaymentNavigation product: AdaptyPaywallProduct,
error: AdaptyError
) { }
Пример события (нажмите, чтобы развернуть)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "web_payment_failed",
"message": "Web payment navigation failed",
"details": {
"underlyingError": "Network connection error"
}
}
}Успешное восстановление покупок
Если восстановление покупки выполнено успешно, вызывается этот метод:
func paywallController(
_ controller: AdaptyPaywallController,
didFinishRestoreWith profile: AdaptyProfile
) { }
Пример события (нажмите, чтобы развернуть)
{
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
},
"subscriptions": [
{
"vendorProductId": "premium_monthly",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
]
}
}Рекомендуем закрыть экран, если у пользователя есть необходимый accessLevel. Как это проверить — читайте в разделе Статус подписки.
Ошибка восстановления покупок
Если восстановление покупки завершается с ошибкой, вызывается этот метод:
public func paywallController(
_ controller: AdaptyPaywallController,
didFailRestoreWith error: AdaptyError
) { }
Пример события (нажмите, чтобы развернуть)
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}Загрузка данных и рендеринг
Ошибки загрузки продуктов
Если массив продуктов не передан при инициализации, AdaptyUI самостоятельно запросит необходимые объекты с сервера. В случае ошибки AdaptyUI сообщит о ней через этот метод:
public func paywallController(
_ controller: AdaptyPaywallController,
didFailLoadingProductsWith error: AdaptyError
) -> Bool {
return true
}
Пример события (нажмите, чтобы развернуть)
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}Если вернуть true, AdaptyUI повторит запрос через 2 секунды.
Ошибки рендеринга
Если при рендеринге интерфейса возникает ошибка, она будет сообщена через этот метод:
public func paywallController(
_ controller: AdaptyPaywallController,
didFailRenderingWith error: AdaptyError
) { }
Пример события (нажмите, чтобы развернуть)
{
"error": {
"code": "rendering_failed",
"message": "Failed to render paywall interface",
"details": {
"underlyingError": "Invalid paywall configuration"
}
}
}В штатной ситуации такие ошибки возникать не должны — если всё же столкнётесь с одной из них, пожалуйста, сообщите нам.