Ios 某些客户端的应用内购买不起作用或无法恢复
我的一些客户告诉我,即使他们进行应用内购买,产品也没有加载。但我的大多数客户都没有这个问题。我是在指示他们做恢复手术,但那没有帮助。问题是,它们可以在其他具有相同苹果id的设备上正确恢复 没有特定的设备或IOS版本,应用程序没有崩溃。它只是说恢复正确或购买正确,但它没有这样做 它让我发疯,因为我在很多设备上都试过,而且它对我来说是正确的 我想分享我使用的代码,这可能会帮助你们理解我不能理解的问题Ios 某些客户端的应用内购买不起作用或无法恢复,ios,objective-c,xcode,in-app-purchase,Ios,Objective C,Xcode,In App Purchase,我的一些客户告诉我,即使他们进行应用内购买,产品也没有加载。但我的大多数客户都没有这个问题。我是在指示他们做恢复手术,但那没有帮助。问题是,它们可以在其他具有相同苹果id的设备上正确恢复 没有特定的设备或IOS版本,应用程序没有崩溃。它只是说恢复正确或购买正确,但它没有这样做 它让我发疯,因为我在很多设备上都试过,而且它对我来说是正确的 我想分享我使用的代码,这可能会帮助你们理解我不能理解的问题 - (void)productsRequest:(SKProductsRequest *)reque
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
SKProduct *validProduct = nil;
NSUInteger count = [response.products count];
if( count > 0 ) {
validProduct = [response.products objectAtIndex:0];
NSLog(@"Products Available!");
[self purchase:validProduct];
}
else if(!validProduct){
NSLog(@"No products available");
[self hideProgressHud];
isProgress = NO;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:LocalizedString(@"Notice") message:LocalizedString(@"Product is not available now.") preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelBtn = [UIAlertAction actionWithTitle:LocalizedString(@"OK") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}];
[alert addAction:cancelBtn];
[self presentViewController:alert animated:true completion:nil];
}
}
- (void)purchase:(SKProduct *)product {
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
NSLog(@"received restored transactions: %lu", (unsigned long)queue.transactions.count);
for(SKPaymentTransaction *transaction in queue.transactions){
if(transaction.transactionState == SKPaymentTransactionStateRestored || transaction.transactionState == SKPaymentTransactionStateRestored){
NSLog(@"Transaction state -> Restored");
NSString *productID = transaction.payment.productIdentifier;
[[InAppPurchaseManager sharedManager] savePurchaseItem:productID];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
[self hideProgressHud];
}
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
[self hideProgressHud];
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
static bool isOnce = false;
for(SKPaymentTransaction *transaction in transactions){
if (transaction.transactionState == SKPaymentTransactionStatePurchasing) {
//called when the user is in the process of purchasing, do not add any of your own code here.
NSLog(@"Transaction state -> Purchasing");
}
else if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
[self refresh_purchaseBtn];
return;
}
else if (transaction.transactionState == SKPaymentTransactionStateRestored) {
NSLog(@"Transaction state -> Restored");
[self hideProgressHud];
isProgress = NO;
//add the same code as you did from SKPaymentTransactionStatePurchased here
NSString *productID = transaction.payment.productIdentifier;
if ([productID isEqualToString:kPURCHASE_ITEM_TYPE_A] || [productID isEqualToString:kPURCHASE_ITEM_TYPE_B] || [productID isEqualToString:kPURCHASE_ITEM_TYPE_C]) {
[[InAppPurchaseManager sharedManager] savePurchaseItem:productID];
}
else {
NSArray *arr = [Workout MR_findByAttribute:@"productId" withValue:productID inContext:ApplicationDelegate.managedObjectContext];
if (arr.count > 0) {
Workout *workout = (Workout *)[arr firstObject];
workout.state = @"purchased";
[ApplicationDelegate.managedObjectContext MR_saveOnlySelfAndWait];
}
[[InAppPurchaseManager sharedManager] savePurchasedReadyProgram:productID];
}
if (!isOnce) {
// UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:LocalizedString(@"Notice") message:LocalizedString(@"Purchased Item restored succesfully") delegate:self cancelButtonTitle:LocalizedString(@"Ok") otherButtonTitles: nil];
// [alertView show];
isOnce = true;
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
[self refresh_purchaseBtn];
}
else if (transaction.transactionState == SKPaymentTransactionStateFailed) {
//called when the transaction does not finish
if(transaction.error.code == SKErrorPaymentCancelled){
NSLog(@"Transaction state -> Cancelled");
//the user cancelled the payment
}
[self hideProgressHud];
isProgress = NO;
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
}
}
你的代码看起来不正确。在
paymentQueueRestoreCompletedTransactionsFinished
中,您不应该做任何事情,除非在需要时更新您的UI。此方法表示恢复已完成,但实际恢复应通过检测updatedTransactions
中的恢复状态来执行。在updatedTransactions
中,您正在调用finishTransaction
以获取SKPaymentTransactionStatePurchased
状态,而不实际持续购买。基本上,SKPaymentTransactionStatePurchased
和SKPaymentTransactionStateRestored
的代码应该是相同的。您的意思是我应该移动[[SKPaymentQueue defaultQueue]finishTransaction:transaction];在paymentQueueRestoreCompletedTransactionsFinished to updatedTransactions中?您的代码看起来不正确。在paymentQueueRestoreCompletedTransactionsFinished
中,您不应该做任何事情,除非在需要时更新您的UI。此方法表示恢复已完成,但实际恢复应通过检测updatedTransactions
中的恢复状态来执行。在updatedTransactions
中,您正在调用finishTransaction
以获取SKPaymentTransactionStatePurchased
状态,而不实际持续购买。基本上,SKPaymentTransactionStatePurchased
和SKPaymentTransactionStateRestored
的代码应该是相同的。您的意思是我应该移动[[SKPaymentQueue defaultQueue]finishTransaction:transaction];在paymentQueueRestoreCompletedTransactionsFinished到updatedTransactions中?