アプリ内購入を試みた後、起動時にアプリがクラッシュするようになったと報告したユーザーが何人かいます。機能していないアプリを削除して再インストールするように依頼し、機能していないネットワーク通信を停止するために機内モードにするよう依頼しようとしました。
とにかくデバイスでエラーを再現できず、アプリ内購入はサンドボックス モードとプロダクション モードで問題なく実行されます。私の考えでは、どういうわけか彼らのトランザクションが起動時のクラッシュを引き起こしている nil productIdentifier を受け取ったのですが、アプリの起動時にどのトランザクション オブザーバー メソッドが呼び出され、問題を解決できるかわかりません。
トランザクションキューを「クリア」するか、起動時に製品識別子がゼロであることをテストして、これらのユーザーが少なくともアプリを再度実行できるようにする方法はありますか? 私は以下のコードを使用してアプリの購入を数百回行いましたが、これは最近発生し始めました. アプリの起動時に呼び出されるヘルパー メソッドはどれですか?
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