#iphone #in-app-purchase #storekit
#iPhone #покупка в приложении #storekit
Вопрос:
Я использую StoreKit для покупок в приложении. Я обнаружил, что API отличается необычным поведением, когда пользователь нажимает кнопку «Отмена».
Например, если я нажимаю «Отмена» на экране «Подтвердить покупку в приложении», я получаю SKPaymentTransactionStateFailed
транзакцию с error.code == SKErrorPaymentCancelled
, как и следовало ожидать.
Но если я нажимаю кнопку Buy, а затем нажимаю Cancel, я получаю Failed
транзакцию с error.code == 0
. error.localizedDescription
Это «Не удается подключиться к iTunes Store», что явно является ложью.
Заманчиво рассматривать все Failed
транзакции как игнорируемые отмены, но я также ясно вижу, что если устройство отключено в режиме полета, я получаю Failed
транзакцию без всплывающего окна с предупреждением; В этом случае мне действительно следует уведомить пользователя, чтобы он объяснил проблему.
Я отмечаю, что MKStoreKit предполагает, что все сбои являются отменами. MKStoreManager
failedTransaction
метод никогда не вызывается; MKStoreObserver
всегда вызывает transactionCanceled
для всех Failed
транзакций. В MKStoreManager.h
комментариях не рекомендуется использовать сообщение об ошибке для transactionCanceled
, что имеет смысл, но тогда кто будет уведомлять пользователя о Failed
не отмененных транзакциях?
Какова наилучшая практика для обработки этих сбоев? Должен ли я проглатывать ошибки? Всегда показывать ошибку, даже если она избыточна?
Ответ №1:
У нас довольно значительная база пользователей, которые покупают товары через мобильные соединения, и мы показываем оповещения только для
code != SKErrorPaymentCancelled amp;amp; code != SKErrorPaymentNotAllowed
По-видимому, это лучшее, что вы можете сделать. Я также видел странное поведение при отмене, о котором вы упоминаете, что, насколько я могу судить, является ошибкой фреймворка.
Ответ №2:
Предыдущий ответ довольно близок. MKStoreKit может автоматически отображать сообщения об ошибках для допустимых условий ошибки, таких как включенный родительский контроль и тому подобное.
Несмотря на это, для обработки отмен покупок я также предоставил делегат (начиная с версии v3.5) под названием transactionCanceled в MKStoreKitDelegate.
Обработайте это и остановите любые индикаторы активности или индикатор прогресса на контроллере просмотра, который выполняет вызов покупки…
Комментарии:
1. MKStoreKit 3.5 не проводит различий между сбоями и отменами. Я зарегистрировал проблему на github github.com/MugunthKumar/MKStoreKit/issues/3 и я исправил это в своем форке.
2. Спасибо! Я объединил ваш запрос на извлечение
3. Теперь, когда мой запрос на извлечение объединен, последний MKStoreKit автоматически отображает ошибку при сбое, а затем вызывает transactionCanceled для делегата, чтобы пользователи могли скрыть счетчик.
4. @Mugunth Почему вы нигде не описываете невозобновляемые подписки, я видел, что так много вопросов, касающихся этого, остались без ответа, почему?
5. невозобновляемые подписки не отличаются от нерасходуемых с точки зрения программиста. Если вы используете MKStoreKit, вам следует добавить свои невозобновляемые подписки в качестве непотребляемых и включить проверку на стороне сервера.
Ответ №3:
Я просто хотел добавить, что ошибки из-за отсутствия подключения к Интернету в основном должны быть обнаружены до любой транзакции с использованием класса достижимости Apple IMO. Таким образом, вам не нужно полагаться на API Apple для получения прямой и распространенной ошибки.
Ответ №4:
Я думаю, что это ваша ответственность и решение о том, показывать предупреждение об отмененной транзакции или нет. Но вы обязательно должны завершить это, иначе все время будет сброшено на сбой. Итак, должно быть что-то вроде этого:
if (transaction.error.code == SKErrorPaymentCancelled) {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
} else {
[self notifyError:transaction.error];
}
Обновить:
Из-за бизнеса по разработке приложений для iPhone: создание и маркетинг приложений, которые успешно работают, мы должны завершать транзакцию после любого обновления до состояния Failed. Было бы интересно узнать, существуют ли ситуации, когда мы не должны этого делать.
Ответ №5:
Все еще есть одна проблема… После нажатия на кнопку «Купить» отобразится другое оповещение и будет запрошена информация об учетной записи.
если я все-таки отменил там, то это перейдет в case SKErrorUnknown: тогда я не могу показать сообщение, подобное этому «Ваша покупка не может быть завершена. Пожалуйста, проверьте настройки вашей сети и повторите попытку позже.»
- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
switch (transaction.error.code) {
case SKErrorUnknown:
NSLog(@"SKErrorUnknown");
break;
case SKErrorClientInvalid:
NSLog(@"SKErrorClientInvalid");
break;
case SKErrorPaymentCancelled:
NSLog(@"SKErrorPaymentCancelled");
break;
case SKErrorPaymentInvalid:
NSLog(@"SKErrorPaymentInvalid");
break;
case SKErrorPaymentNotAllowed:
NSLog(@"SKErrorPaymentNotAllowed");
break;
default:
NSLog(@"No Match Found for error");
break;
}
NSLog(@"transaction.error.code %@",[transaction.error description]);
if (transaction.error.code == SKErrorPaymentCancelled) {
[[MKStoreManager sharedManager] transactionCanceled:transaction];
} else {
[[MKStoreManager sharedManager] failedTransaction:transaction];
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}