una soporte seguridad saber restaurar recuperar mis gratis copia compras como apps app anterior iphone objective-c in-app-purchase restore

soporte - restaurar iphone



Rechazo de Apple debido a la compra en la aplicaciĆ³n no implementa restauraciĆ³n (2)

Me rechazó Apple con un mensaje que decía:

... Además, encontramos que mientras su aplicación ofrece compras dentro de la aplicación que pueden ser restauradas, no incluye la función de "Restauración" requerida para permitir a los usuarios restaurar las compras compradas previamente dentro de la aplicación, como se especifica en la sección Restauración de transacciones de la Guía de programación de compras desde la aplicación:

"... si su aplicación admite tipos de productos que deben ser recuperables, debe incluir una interfaz que permita a los usuarios restaurar estas compras. Esta interfaz le permite a un usuario agregar el producto a otros dispositivos o, si se eliminó el dispositivo original, restaurar la transacción en el dispositivo original ".

Para restaurar los productos comprados previamente dentro de la aplicación, sería apropiado proporcionar un botón "Restaurar" e iniciar el proceso de restauración cuando el usuario toca el botón "Restaurar".

Para obtener más información sobre la restauración de transacciones y la verificación del recibo de la tienda, consulte la Guía de programación de compras desde la aplicación. ...

Y encontré esta page , y seguí el código de ejemplo, pero después de llamar

- (void) checkPurchasedItems{ [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; }

¡Otro delegado no fue despedido!

- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue

Solo muestra una vista de alerta para permitirle ingresar su ID de Apple ... ¿y no pasó nada?

Establecí un punto de ruptura, pero no se detendría como decía el ejemplo.

¿Alguna idea sobre lo que está mal con mi código?


Además de agregar restoreCompletedTransactions , debe controlar cómo se restauran realmente sus iaps al usuario y cómo se proporciona el contenido al usuario.

Básicamente, debe recordar la forma en que proporcionó el artículo a su usuario cuando lo compró originalmente.

Aquí hay un buen tutorial.

Por ejemplo , así es como restauro productos en una de mis aplicaciones.

Restaurar la transacción

- (void)restoreTransaction:(SKPaymentTransaction *)transaction { isRestoring = YES; [self recordTransaction: transaction]; /* This is where I provide the content to the user: */ [self provideContent: transaction.originalTransaction.payment.productIdentifier]; [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; }

Transacción completada

- (void)completeTransaction:(SKPaymentTransaction *)transaction { [self recordTransaction: transaction]; [self provideContent: transaction.payment.productIdentifier]; [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; }

Cola de pago

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: [self completeTransaction:transaction]; break; case SKPaymentTransactionStateFailed: if (transaction.error.code == SKErrorPaymentCancelled) { /// user has cancelled [[NSNotificationCenter defaultCenter] postNotificationName:@"hideRestoring" object:nil]; } [self failedTransaction:transaction]; break; case SKPaymentTransactionStateRestored: [self restoreTransaction:transaction]; default: break; } } }

Proporcionar el contenido

- (void)provideContent:(NSString *)productIdentifier { int index; NSMutableDictionary * purchased = [NSMutableDictionary dictionaryWithContentsOfFile:EXTRAS_PATH]; NSArray * availableProducts = [NSArray arrayWithContentsOfURL:[NSURL URLWithString:SCANNER_IN_APP_PURCHASES]]; if ( isRestoring ) { for ( index = 0; index < [availableProducts count]; index++ ) { //NSLog(@"productIdentifier: %@",productIdentifier); //NSLog(@"Product: %@",[availableProducts objectAtIndex:index]); if ( [productIdentifier isEqualToString:[[availableProducts objectAtIndex:index] objectForKey:@"BundleID"]] ) { [purchased setObject:[availableProducts objectAtIndex:index] forKey:productIdentifier]; [purchased writeToFile:EXTRAS_PATH atomically:YES]; [_purchasedProducts addObject:productIdentifier]; } } } else { index = [[[NSUserDefaults standardUserDefaults] objectForKey:@"kTempProductPurchasingIndex"] intValue]; if ( [productIdentifier isEqualToString:[[availableProducts objectAtIndex:index] objectForKey:@"BundleID"]] ) { [purchased setObject:[availableProducts objectAtIndex:index] forKey:productIdentifier]; [purchased writeToFile:EXTRAS_PATH atomically:YES]; [_purchasedProducts addObject:productIdentifier]; } } [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchasedNotification object:productIdentifier]; }


[[SKPaymentQueue defaultQueue] addTransactionObserver:self]; [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

Añadir la línea anterior también. paymentQueueRestoreCompletedTransactionsFinished debe llamar a su función paymentQueueRestoreCompletedTransactionsFinished .