iOS в приложениях: только один платеж добавлен в SKPaymentQueue, но метод SKPaymentTransactionObserver вызывается несколько раз - PullRequest
3 голосов
/ 04 ноября 2011

Я тестирую IAP, используя тестового пользователя (в песочнице), у меня есть класс, который реализует протокол SKPaymentTransactionObserver, и когда пользователь выбирает определенную ячейку табличного представления, я инициирую платеж:

SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier];
[[SKPaymentQueue defaultQueue] addPayment:payment];

Это делается только один раз, и я проверил: код вызывается один раз. Проблема в том, что '- (void) paymentQueue: (SKPaymentQueue *) queue updatedTransactions: (NSArray *) транзакции "иногда вызывается несколько раз, и я не могу понять, почему. Это не всегда происходит, но никогда не должно происходить.

Кто-нибудь сталкивался с таким поведением при тестировании в песочнице (было бы большой проблемой, если бы это произошло в реальном сценарии)?

Ответы [ 3 ]

3 голосов
/ 08 ноября 2011

Я обычно «назначаю» своих делегатов, но на этот раз делегат класса, который обрабатывает всю обработку транзакций, был сохранен.И делегат (контроллер представления), и класс покупок в приложении просочились.Из-за этого каждый раз, когда я представлял контроллер представления, создавался другой экземпляр и другой набор делегатов.Во время обработки транзакции было зарегистрировано столько экземпляров класса покупок в приложении, которые находились в свободном роуминге :), сколько раз было представлено представление.Таким образом, это была не проблема IAP, а проблема управления вниманием и памятью.

0 голосов
/ 18 апреля 2017

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

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

@implementation MyViewController : SomeParentController<SKPaymentTransactionObserver>

- (void)startPayment:(SKPayment *)payment {
  SKPaymentQueue *queue = [SKPaymentQueue defaultQueue];

  /* Unless MyViewController is a singleton this line of code will add a new observer
   * to the default queue. The observer is retained and every time a transaction is added
   * to the queue the callback code will be executed on all registered observers.
   */
  [queue addTransactionObserver:self];
  [SKPaymentQueue addPayment:payment];
}

- (void)paymentQueue:(SKPaymentQueue *)queue 
   updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions {
   // Your transaction processing code here
}

@end
0 голосов
/ 04 ноября 2011

Это нормальное поведение и причина, по которой вы используете transactionState, чтобы узнать состояние любых текущих транзакций. Одним из возможных состояний транзакции является SKPaymentTransactionStatePurchasing, т. Е. Система сообщает вам, что в транзакции был некоторый прогресс, но она еще не завершена.

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

...