Q: How I can detect when this event (currently subscribed) has occurred so that I can process the transaction and grant access to my app.
para detectar cuándo existe la suscripción a través de la validación con Apple (utilizo código del sitio web php para hacer esto), se obtiene una respuesta "código de estado" de nuevo, y puede verificar si se trata de un código 21006 (suscripción es caducado) u otros (considero que cualquier cosa que no sea 0 y 21006 sea un error real).
La forma en que hago las cosas es almacenar los detalles de la transacción dentro de un archivo PLIST que almaceno en el directorio de documentos.
Se podría añadir campos adicionales a la PLIST como expiryDates, banderas booleanas, etc.
esta manera usted tiene una copia del recibo, aunque siempre se debe validarlo, ya que puede haber expirado.
Q: En el paymentQueue: updatedTransactions: método del observador que está llegando a través como SKPaymentTransactionStateFailed. ¿Cómo distingo entre este tipo de falla y otras fallas como que el usuario presiona los botones de cancelar?
Utiliza una instrucción switch en el método updatedTransactions para determinar los diferentes tipos de respuestas.
Ejemplo
-(void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
NSString *message = [NSString stringWithFormat:@"Transaction failed with error - %@", error.localizedDescription];
NSLog(@"Error - %@", message);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"
message:message
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
NSLog(@"updatedTransactions");
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchasing:
// take action whilst processing payment
break;
case SKPaymentTransactionStatePurchased:
// take action when feature is purchased
break;
case SKPaymentTransactionStateRestored:
// take action to restore the app as if it was purchased
break;
case SKPaymentTransactionStateFailed:
if (transaction.error.code != SKErrorPaymentCancelled)
{
// Do something with the error
} // end if
break;
default:
break;
} // end switch
} // next
El TransactionStateFailed maneja los fracasos, a pesar de que no codifican para la cancelación ya que no hay razón para que yo hago en mi aplicación.
P: ¿Envío la transacción que se devuelve o necesito llamar a restorePreviousTransactions.
Creo StoreKit maneja internamente con este método y métodos restorePreviousTransaction finishTransaction
es decir,
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
para terminar transacciones
Espero que esto ayude