iPhone inApp Покупка очереди не будет очищаться - PullRequest
8 голосов
/ 19 мая 2011

В моем приложении есть настройка покупки InApp. Хотя у меня странное поведение. Каждый раз, когда я запускаю приложение, я звоню

[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

для настройки начального наблюдателя. Однако это сразу вызывает

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

с полным массивом каждой транзакции. Я пытался просто позвонить

[[SKPaymentQueue defaultQueue] finishTransaction: transaction];

для каждой из этих транзакций, затем перезапускаю приложение, но paymentQueue все еще срабатывает, как только я вызываю addTransactionObserver. Моя главная цель сейчас - просто очистить очередь транзакций и начать очистку. Я не знаю, как я попал в это состояние и как из него выйти.

Ответы [ 5 ]

5 голосов
/ 08 июня 2011

Убедитесь, что вы реализовали этот метод:

-(void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions;
3 голосов
/ 20 июня 2015

Поместите это куда-нибудь, чтобы очистить очередь (возможно, ваш метод загрузки, но удалите его в вашем конечном приложении):

for (SKPaymentTransaction* transaction in [[SKPaymentQueue defaultQueue] transactions]) {
     [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

Когда вызывается finishTransaction, вызывается метод removeTransaction наблюдателякогда каждый перемещается.

У меня было 30 в очереди, и я получил 30 вызовов этого метода.

1 голос
/ 13 сентября 2017

Я думаю, что ваша проблема связана с учетными записями пользователей песочницы в iTunes Connect. Если у вас нет пользователей с песочницей, это руководство было очень полезно для их настройки:
https://support.magplus.com/hc/en-us/articles/203809008-iOS-How-to-Test-In-App-Purchases-in-Your-App

Если у вас есть пользователи Песочницы:

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

Согласно документации на finishTransaction:

// Asynchronous.  
// Remove a finished (i.e. failed or completed) transaction from the queue.
// Attempting to finish a purchasing transaction will throw an exception.

Чтобы безопасно удалить завершенные транзакции:

for transaction in SKPaymentQueue.default().transactions {
    guard 
        transaction.transactionState != .purchasing, 
        transaction.transactionState != .deferred 
    else { 
        //Optionally provide user feedback for pending or processing transactions
        return
    }

    //Transaction can now be safely finished
    SKPaymentQueue.default().finishTransaction(transaction)   
}

Документация по .purchasing и .deferred довольно расплывчата:

case purchasing // Transaction is being added to the server queue.

case deferred  // The transaction is in the queue, but its final status is pending external action.

Насколько я понимаю, обработка ожидающих и / или обрабатывающих транзакций должна быть довольно пассивной. Приложение сделало все, что ему было нужно, и ожидает ответа от сервера iTunes Store или какой-либо другой зависимости (например, авторизация платежа).

paymentQueue: updatedTransactions: будет вызываться в очереди SKPaymentTransactionObserver при обновлении транзакции.

Поскольку ваша очередь транзакций застряла в подвешенном состоянии, я готов поспорить, что все транзакции в вашей очереди находятся в состоянии .purchasing. Это, скорее всего, ошибка в iTunes Connect / пользователях песочницы / производственных учетных записях iTunes. Другие, в том числе и я, тоже имели эту проблему. Для этого есть отчет об ошибке. Попробуйте воссоздать / изменить пароль пользователя вашей песочницы или создать нового пользователя песочницы для тестирования.

Больше информации здесь: https://forums.developer.apple.com/thread/70418

1 голос
/ 22 июня 2017

С SKPaymentTransactionObserver:PaymentQueue.. звоните:

SKPaymentQueue.default().finishTransaction(transaction)

Обратите внимание, что вы не можете звонить для всех типов. Вызов finishTransaction для .purchasing завершится с ошибкой. Таким образом, for через все транзакции не является полным решением.

Когда вы звоните finishTransaction для .purchasing:

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot finish a purchasing transaction'
1 голос
/ 06 ноября 2016

Вы должны быть уверены, что завершаете транзакцию каждый раз, когда совершаете покупку или восстанавливаете продукт. Если вы столкнулись с этой проблемой, вы должны очистить свою очередь, а затем соответствующим образом разработать логику. Быструю очистку можно получить, запустив что-то вроде этого в swift 3. (что совпадает с предыдущим ответом). Но это не должно быть в вашем реальном приложении.

func cleanUp() {

    for transaction in SKPaymentQueue.default().transactions {

        SKPaymentQueue.default().finishTransaction(transaction)   
    }
}

Также вы должны добавить и удалить своего наблюдателя в appDelegate. Это рекомендация, и лучше всего избегать проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...