2012-11-26 7 views
8

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

На данный момент я просто получаю SKPaymentTransactionStateFailed в paymentQueue: updatedTransactions: метод как после отмены нажатия кнопок пользователя, так и, например, при отсутствии Интернета. Любой способ дифференцировать эти два случая?

ответ

0

Проверьте установленное свойство ошибки SKPaymentTransaction. Кроме того, вы можете использовать класс Reachability Apple, чтобы определить, доступен ли Интернет до начала транзакции.

ошибка Объект, описывающий ошибку, возникшую во время обработки транзакции. (Только для чтения)

@property (неатомической, только для чтения) NSError * Ошибка Обсуждение Свойство ошибки не определен, кроме случаев, когда transactionState установлен в SKPaymentTransactionStateFailed. Ваше приложение может прочитать свойство ошибки, чтобы определить, почему транзакция завершилась неудачно.

Доступность Доступно в iOS 3.0 и новее. Объявлен В SKPaymentTransaction.h

+2

Это странная часть об этом. Когда я нажимаю кнопку отмены, я все равно получаю SKPaymentTransactionStateFailed в paymentQueue: updatedTransactions: метод и следующая ошибка: Error Domain = SKErrorDomain Code = 2 «Не удается подключиться к iTunes Store» – dariaa

+0

Это несчастливо.Поэтому я бы проверил подключение к Интернету с использованием класса Reachability от Apple, и если у вас есть возможность подключения, то вы знаете, что он был либо отменен, либо покупка была неудачной с сервером. Я бы также опубликовал отчет об ошибке, в котором указано, что свойство ошибки не работает как задокументированное, и попросите исправить. –

+0

Это не проблема подключения - по какой-то причине ошибка является одинаковой при отмене транзакции или при ее отсутствии по любой другой причине. – Stavash

1

Возможно, вы используете Учебный код Ray Wunderlich для покупки приложений. Там Кодекс говорит:

- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers { 

if ((self = [super init])) { 

    // Store product identifiers 
    _productIdentifiers = productIdentifiers; 

    // Check for previously purchased products 
    _purchasedProductIdentifiers = [NSMutableSet set]; 
    for (NSString * productIdentifier in _productIdentifiers) { 
     BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier]; 
     if (productPurchased) { 
      [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; // CHECK THIS 
      [_purchasedProductIdentifiers addObject:productIdentifier]; 
      NSLog(@"Previously purchased: %@", productIdentifier); 
     } else { 
      NSLog(@"Not purchased: %@", productIdentifier); 
     } 
    } 

Там вы можете увидеть, что addTransactionObserver только называется, если продукт уже pruchased. Если вы переместите эту строку кода перед запросом if, вы получите желаемый результат.

[[SKPaymentQueue defaultQueue] addTransactionObserver:self]; // MOVE HERE 
if (productPurchased) { 
    [_purchasedProductIdentifiers addObject:productIdentifier]; 
    NSLog(@"Previously purchased: %@", productIdentifier); 
} else { 
    NSLog(@"Not purchased: %@", productIdentifier); 
}     

В методе failedTransaction теперь вы можете вызвать

[[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductPurchasedNotification object:nil userInfo:nil]; 

Теперь вы можете проверить нулевую величину, посланное уведомления в текущем режиме просмотра

15

Этот код работает для меня:

if (transaction.error.code != SKErrorPaymentCancelled) { 
    NSLog(@"Other error"); 
} else { 
    NSLog(@"User canceled"); 
} 
9

Ответ Эллен совершенен. Только в случае, если кто-то интересно о других случаях

switch (transaction.error.code) { 
     case SKErrorUnknown: 
      //Unknown error 
      break; 
     case SKErrorClientInvalid: 
      // client is not allowed to issue the request, etc. 
      break; 
     case SKErrorPaymentCancelled: 
      // user cancelled the request, etc. 
      break; 
     case SKErrorPaymentInvalid: 
      // purchase identifier was invalid, etc. 
      break; 
     case SKErrorPaymentNotAllowed: 
      // this device is not allowed to make the payment 
      break; 
     default: 
      break; 
} 
1

Swift 2,2

В случае, когда вы получаете .Failed ответ в paymentQueue, было бы хорошей идеей, чтобы обработать все ошибки, которые вы Можно.

if let error = transaction.error { 
    if error.domain == SKErrorDomain { 
     // handle all possible errors 
     switch (error.code) { 
     case SKErrorCode.Unknown.rawValue: 
      print("Unknown error") 
      break; 
     case SKErrorCode.ClientInvalid.rawValue: 
      print("client is not allowed to issue the request") 
      break; 
     case SKErrorCode.PaymentCancelled.rawValue: 
      print("user cancelled the request") 
      break; 
     case SKErrorCode.PaymentInvalid.rawValue: 
      print("purchase identifier was invalid") 
      break; 
     case SKErrorCode.PaymentNotAllowed.rawValue: 
      print("this device is not allowed to make the payment") 
      break; 
     default: 
      break; 
     } 
    } 
} 
4

Вот рабочий код на Swift 3.0:

if let error = transaction.error as? NSError { 

       if error.domain == SKErrorDomain { 
        // handle all possible errors 
        switch (error.code) { 
        case SKError.unknown.rawValue: 
         print("Unknown error") 

        case SKError.clientInvalid.rawValue: 
         print("client is not allowed to issue the request") 

        case SKError.paymentCancelled.rawValue: 
         print("user cancelled the request") 

        case SKError.paymentInvalid.rawValue: 
         print("purchase identifier was invalid") 

        case SKError.paymentNotAllowed.rawValue: 
         print("this device is not allowed to make the payment") 

        default: 
         break; 
      } 
    } 
+2

Если вы не передали его в 'NSError', он останется' SKError', и вы можете просто сделать 'case SKError.unknown:'; нет необходимости использовать '.rawValue'. –

Смежные вопросы