この問題は私にしばらくの間頭痛を与えてきました。
私のアプリは自動更新可能なサブスクリプションモデルで動作します。Appleを通じて購入が正常に完了したときに通知されるSKPaymentQueuetransactionObserverがあります。この時点で、Appleの領収書をサーバーに送信して確認します。確認したら、成功コールをアプリに送り返します。アプリはコンテンツをユーザーに提供し、続いてトランザクションでfinishTransaction:を呼び出します(ドキュメントによると、これは適切なアクションです)。
問題は、finishTransactionを呼び出すのをこれだけ長く待つことです。Appleがそれが呼び出されることを期待した後(3〜4秒)、トランザクションが実際に「終了」することを禁止しています。アプリ内で正常に購入し(そしてfinishTransaction:が呼び出された)、アプリを終了して(Xcodeで「停止」)再度実行すると、起動直後に1つ、2つ、3つ、場合によっては4つになります。または、UIがロードされる前のSKPaymentQueue内の5つのトランザクション。
Appleとのトランザクションが完了した後に行われる私のサーバーへの呼び出しは次のとおりです。
-(void)completeTransaction:(SKPaymentTransaction *)transaction
{
NSLog(@"complete transaction");
[self sendReceiptToServer:transaction];
}
-(void)sendReceiptToServer:(SKPaymentTransaction*)transaction
{
NSString *rawReceiptData = [[NSString alloc] initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:rawReceiptData, @"receipt", [[UserSingleton sharedInstance] memberID], @"member", nil];
NSMutableURLRequest *request = [[HTTPRequestSingleton sharedClient] requestWithMethod:@"POST" path:cFunctionAddCredits parameters:params];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(@"%@", JSON);
NSString *creditsString = [JSON valueForKey:@"limit"];
int numberOfCredits = [creditsString intValue];
[self provideContent:transaction.payment.productIdentifier withNumberOfCredits:numberOfCredits];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(@"failed to send receipt to server");
[[NSNotificationCenter defaultCenter] postNotificationName:cFailedToSendReceiptToServer object:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}];
[operation start];
}
ご覧のとおり[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
、サーバーへのリクエストの成功ブロックまたは失敗ブロック内で呼び出されます。これはどういうわけか問題がありますか?
*編集*確認のためにレシートをサーバーに送信する前
に電話をかけた場合、この問題は発生しないようですSKPaymentQueue:finishTransaction:
。これにより、ネットワーク要求ブロック内でレシートを呼び出すことが実際に問題を引き起こしていると思われます。しかし、これは物事を処理する正しい方法ではないので、私はまだ立ち往生しています。
*編集2 *finishTransaction:
領収書をサーバーに送信する前に電話
をかけた場合でも、アプリの起動時にトランザクションが「復活」することがあります。どうしたの?