在应用程序购买后,应用程序在启动时崩溃。 产品识别=无?

我有几个用户报告说,尝试在应用程序内购买应用程序现在崩溃在启动。 我已经要求他们删除并重新安装那些没有工作的应用程序,并试图要求他们进入飞机模式,以阻止任何没有工作的networking通信。

我无法在我的设备上复制错误,我的应用程序购买在沙箱和生产模式下都能很好地完成。 我的想法是,不知何故,他们的交易收到了一个零产品标识导致启动崩溃,但我不知道什么事情观察员方法在应用程序启动时被调用,我可以解决他们的问题。

有没有办法“清除”交易队列,或者在启动时testing零产品标识符,并允许这些用户至less再次运行应用程序? 我使用下面的代码做了数百次的应用程序购买,这只是最近开始发生。 应用程序启动时调用哪个助手方法?

在AppDelegate.m中

[[SKPaymentQueue defaultQueue] addTransactionObserver:[MovieClockIAPHelper sharedHelper]]; 

在应用帮手代码中:

 - (id)initWithProductIdentifiers:(NSSet *)productIdentifiers { if ((self = [super init])) { // Store product identifiers _productIdentifiers = [productIdentifiers retain]; // Check for previously purchased products NSMutableSet * purchasedProducts = [NSMutableSet set]; for (NSString * productIdentifier in _productIdentifiers) { BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier]; if (productPurchased) { [purchasedProducts addObject:productIdentifier]; NSLog(@"Previously purchased: %@", productIdentifier); } else{ NSLog(@"Not purchased: %@", productIdentifier); } } self.purchasedProducts = purchasedProducts; } return self; } - (void)requestProducts { self.request = [[[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers] autorelease]; _request.delegate = self; [_request start]; } - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { NSLog(@"Received products results..."); self.products = response.products; self.request = nil; [[NSNotificationCenter defaultCenter] postNotificationName:kProductsLoadedNotification object:_products]; } - (void)restoreCompletedTransactions { [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; } - (void)provideContent:(NSString *)productIdentifier { NSLog(@"Toggling flag for: %@", productIdentifier); [[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:productIdentifier]; [[NSUserDefaults standardUserDefaults] synchronize]; [_purchasedProducts addObject:productIdentifier]; [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchasedNotification object:productIdentifier]; } - (void)completeTransaction:(SKPaymentTransaction *)transaction { NSLog(@"completeTransaction..."); [self recordTransaction: transaction]; [self provideContent: transaction.payment.productIdentifier]; [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } - (void)restoreTransaction:(SKPaymentTransaction *)transaction { NSLog(@"restoreTransaction..."); [self recordTransaction: transaction]; [self provideContent: transaction.originalTransaction.payment.productIdentifier]; [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } - (void)failedTransaction:(SKPaymentTransaction *)transaction { if (transaction.error.code != SKErrorPaymentCancelled) { NSLog(@"Transaction error: %@", transaction.error.localizedDescription); } [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchaseFailedNotification object:transaction]; [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { NSLog(@"in the payment queue"); for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: [self completeTransaction:transaction]; break; case SKPaymentTransactionStateFailed: [self failedTransaction:transaction]; break; case SKPaymentTransactionStateRestored: [self restoreTransaction:transaction]; default: break; } } } -(void)buyProduct:(SKProduct *)product { NSLog(@"In buyproduct Buying %@...", product.productIdentifier); SKPayment *payment = [SKPayment paymentWithProduct:product]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } - (void)dealloc { [_productIdentifiers release]; _productIdentifiers = nil; [_products release]; _products = nil; [_purchasedProducts release]; _purchasedProducts = nil; [_request release]; _request = nil; [super dealloc]; } @end 

当事务处于SKPaymentTransactionStateRestored状态时,我遇到了类似的问题。 我的testing表明这可能是IOS 7.0.3的一个问题,但我还没有能够validation这一点。

StoreKit保存应用程序必须完成的事务的持久列表。 正如您所注意到的那样,每次启动都会报告交易,直到完成。

我们实施的解决scheme是在入口点使用之前检查产品标识是否为零。

 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions 

即使我们收到一个没有产品标识符的交易,我们也能成功地调用finishTransaction

我希望这有帮助。

我的一个用户在四天前抱怨同样的问题,并能够给我发送一个崩溃日志。 他在iPhone 5,2上使用iOS 7.0.3。 在尝试使用originalTransaction.payment的productIdentifier属性构build字典时,在识别SKPaymentTransactionStateRestored之后发生崩溃:

 NSDictionary* userInfoDict = @{@"productID":transaction.payment.productIdentifier}; 

我认为originalTransaction或其属性付款或productIdentifier是零。 我从transaction.payment.productIdentifier中存储productIdentifier,而不是从transaction.originalTransaction.payment.productIdentifier中恢复,并将其作为productIdentifier使用:

 case SKPaymentTransactionStateRestored: { NSString *productID = transaction.originalTransaction.payment.productIdentifier; if (!productID) { productID = transaction.payment.productIdentifier; } [self handlePurchaseSuccessful:transaction.originalTransaction productIdentifier:productID]; } 

如果能解决这个问题,还在等待审查/反馈。

详细阐述Shawn的回答,在- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions你可能有这样的代码:

 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: [self completeTransaction:transaction]; break; case SKPaymentTransactionStateFailed: [self failedTransaction:transaction]; break; case SKPaymentTransactionStateRestored: [self restoreTransaction:transaction]; default: break; } } } - (void) restoreTransaction: (SKPaymentTransaction *)transaction { /* Handle restore here */ [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } 

您可以在restoreTransaction:处理nil productIdentifier restoreTransaction:通过添加检查来查看productIdentifier是否为零,如下所示:

 - (void) restoreTransaction: (SKPaymentTransaction *)transaction { if (!transaction.originalTransaction.payment.productIdentifier) { NSLog(@"productIdentifier is nil; Apple bug?"); [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; return; } /* Handle restore here */ [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } 

这种技术在我的应用程序中解决了我的问题。 该应用程序启动,logging“productIdentifier为零;苹果的bug? 并没有崩溃。 当我手动重新恢复交易时,苹果发送了一个有效的交易,并且该应用按devise工作。

我解决了这个问题, 因为Marimba公布在上面 ,它帮助我们的客户:

 case SKPaymentTransactionStateRestored: { NSString *productID = transaction.originalTransaction.payment.productIdentifier; if (productID == nil) { productID = transaction.payment.productIdentifier; } [self handlePurchaseSuccessful:transaction.originalTransaction productIdentifier:productID]; } 

我有同样的问题paymentQueue:updatedTransactions:SKPaymentTransaction实例调用, SKPaymentTransaction状态, SKPaymentTransactionStateRestored nil productIdentifier

这听起来很奇怪,可能是7.0.3 SDK错误。

你们都还在用SDK 6进行编译吗?

我即将重新提交我的应用程序到商店,看看问题是否得到解决,但只是完成这样的交易,但我希望有一个有效的productIdentifier其他事务将被处理,现在该应用程序不会崩溃,所以我知道什么恢复。