2012-11-26 17 views
8

Come posso controllare se il pulsante di annullamento utente toccato (quando gli è stato chiesto se desidera acquistare smth o forse se ha già acquistato questo SKProduct se vuole scaricarlo)?Verifica se l'utente ha annullato SKPaymentTransaction

Per ora ricevo SKPaymentTransactionStateFailed in paymentQueue: updatedTransactions: metodo sia dopo che l'utente tocca il pulsante Annulla e, ad esempio, quando non c'è Internet. Un modo per differenziare questi due casi?

risposta

0

Controllare la proprietà dell'errore SKPaymentTransaction impostata. Inoltre, è possibile utilizzare la classe Reachability di Apple per determinare se Internet è disponibile prima di iniziare la transazione.

errore Un oggetto che descrive l'errore che si è verificato durante l'elaborazione della transazione. (Sola lettura)

@property (nonatomic, sola lettura) NSError * errore Discussione La proprietà errore è undefined se non quando transactionState è impostato su SKPaymentTransactionStateFailed. L'applicazione può leggere la proprietà dell'errore per determinare il motivo per cui la transazione ha avuto esito negativo.

Disponibilità Disponibile in iOS 3.0 e versioni successive. dichiarati nel SKPaymentTransaction.h

+2

Questa è la parte strana su di esso. Quando premo il pulsante Annulla ricevo ancora SKPaymentTransactionStateFailed in paymentQueue: updatedTransactions: metodo e il seguente errore: Errore Domain = SKErrorDomain Code = 2 "Impossibile connettersi a iTunes Store" – dariaa

+0

Questo è sfortunato.Quindi controllerei la connettività Internet utilizzando la classe Reachability di Apple, quindi se disponi di connettività, saprai che è stata annullata o che l'acquisto non è riuscito con il server in qualche modo. Vorrei anche presentare una segnalazione di errore che affermasse che la proprietà dell'errore non funziona come documentato e chiedere una soluzione. –

+0

Questo non è un problema di connettività: per qualche ragione, l'errore è lo stesso quando si annulla la transazione o quando fallisce per qualsiasi altro motivo. – Stavash

1

Forse state utilizzando il codice Tutorial di Ray Wunderlich per in App Purchase. C'è il Codice dice:

- (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); 
     } 
    } 

Ci si può vedere, che addTransactionObserver viene chiamato solo se il prodotto è già pruchased. Se sposti questa riga di codice davanti alla query if, otterrai il risultato desiderato.

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

Nel metodo failedTransaction ora è possibile chiamare

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

Ora è possibile controllare il valore nil inviato dal notifica nel corrente vista

15

Questo codice funziona per me:

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

La risposta di Ellen è perfetta. Solo nel caso qualcuno si interroga su altri casi

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

Nel caso in cui si ottiene una risposta .Failed nel paymentQueue, sarebbe una buona idea per gestire tutti gli errori che può.

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

Ecco il codice a lavorare su 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

Se non lo si esegue in un 'NSError', rimarrà un' SKError' e si può semplicemente fare 'caso SKError.unknown:'; non c'è bisogno di usare '.rawValue'. –

Problemi correlati