Баг при использовании in-app purchases

Использую код для покупок внутри приложении на основе этого ответа. Но столкнулся с некоторыми странными проблемами. Например:

У меня есть FirstViewController с заблокированным платным содержимым и PurchasesViewController с кнопками покупки. Когда я нажимаю кнопку покупки в PurchasesViewController, подтверждаю покупку и жду несколько секунд, чтобы получить уведомление об успешной покупке, а затем я возвращаюсь к FirstViewController и вижу, что содержимое разблокировано. В этом примере все работает нормально. Но...

Проблема:

Если я нажимаю кнопку покупки в PurchasesViewController, подтверждаю покупку и, не дожидаясь уведомления, я возвращаюсь в FirstViewController и получаю уведомление об успешной покупке там. Тогда мой контент не будет разблокирован. Даже если я перезапущу приложение, контент не разблокирован все равно. Но если я нажму на кнопку «восстановить покупки», все разблокируется(значит покупка была успешно куплена в первый раз).

Эта проблема может сбивать с толку пользователя. Получается, что они покупают, но контент не получают. А кнопку восстановления не все догадаются нажать. Поэтому как вариант решения, я хочу заблокировать интерфейс и показывать «индикатор активности», пока пользователь не получит уведомление об успешной покупке. Чтобы он не смог перейти в первый контроллер и не произошел баг. И после того, как пользователь нажмет «ОК» в окне уведомления, я хочу разблокировать интерфейс и удалить «индикатор активности». Но как это сделать? Где и когда мне следует вызывать функцию блокировки интерфейса?


Ответы (1 шт):

Автор решения: Denis Shchigolev

В указанном промере нет валидации чека. Но если используется данный пример, то

let activitiIndicator = UIActivityIndicatorView()

вызывается в:

internal func processPurchaseStatus(_ status: PurchaseStatus) {
        switch status.state {
        case .initiated:
            // тут запускаем индикатор
             activitiIndicator.startAnimating()
        case .complete:
            if let productID = status.transaction?.payment.productIdentifier {
                //тут выключаем
                activitiIndicator.stopAnimating()
                UserDefaults.standard.set(true , forKey: productID)
            }
        case .cancelled:
            //и тут выключаем, если пользователь прервал покупку
                activitiIndicator.stopAnimating()
        case .failed:
            //тут выключаем если ошибка и сообщаем о ней
            activitiIndicator.stopAnimating()
            print("Ошибка транзакции")
        }
    }
→ Ссылка