Skip to content

Commit 19ab18e

Browse files
committed
Fix to ensure restoreTransactions completion callback is called robotmedia#150
Inside RMStore, when the paymentQueue:updatedTransactions is called after a restore, a pendingRestoredTransactions counter was incremented/decremented as transactions were processed. However, in our case updateTransactions callback was called twice, so 2x the amount of transactions were added to the pendingRestoredTransactions counter. The problem was the counter was incremented twice but only decremented once for each transaction. WHen the code reached notifyRestoreTransactionFinishedIfApplicableAfterTransaction, the counter was checked but was not equal to zero, so the callback wasn't called, even though all the transactions were processed. The fix was to use a MutableSet to store transaction identifiers that were pending restore, which prevents duplicate transactions to be handled. The callback is now always called after transactions are restored.
1 parent 9b4f37c commit 19ab18e

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

RMStore/RMStore.m

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ @implementation RMStore {
138138

139139
NSMutableArray *_storedStorePayments;
140140

141-
NSInteger _pendingRestoredTransactionsCount;
141+
NSMutableSet *_pendingRestoredTransactionIds;
142142
BOOL _restoredCompletedTransactionsFinished;
143143

144144
SKReceiptRefreshRequest *_refreshReceiptRequest;
@@ -158,6 +158,7 @@ - (instancetype) init
158158
_productsRequestDelegates = [NSMutableSet set];
159159
_restoredTransactions = [NSMutableArray array];
160160
_storedStorePayments = [NSMutableArray array];
161+
_pendingRestoredTransactionIds = [NSMutableSet set];
161162
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
162163
}
163164
return self;
@@ -265,7 +266,7 @@ - (void)restoreTransactionsOnSuccess:(void (^)(NSArray *transactions))successBlo
265266
failure:(void (^)(NSError *error))failureBlock
266267
{
267268
_restoredCompletedTransactionsFinished = NO;
268-
_pendingRestoredTransactionsCount = 0;
269+
[_pendingRestoredTransactionIds removeAllObjects];
269270
_restoredTransactions = [NSMutableArray array];
270271
_restoreTransactionsSuccessBlock = successBlock;
271272
_restoreTransactionsFailureBlock = failureBlock;
@@ -278,7 +279,7 @@ - (void)restoreTransactionsOfUser:(NSString*)userIdentifier
278279
{
279280
NSAssert([[SKPaymentQueue defaultQueue] respondsToSelector:@selector(restoreCompletedTransactionsWithApplicationUsername:)], @"restoreCompletedTransactionsWithApplicationUsername: not supported in this iOS version. Use restoreTransactionsOnSuccess:failure: instead.");
280281
_restoredCompletedTransactionsFinished = NO;
281-
_pendingRestoredTransactionsCount = 0;
282+
[_pendingRestoredTransactionIds removeAllObjects];
282283
_restoreTransactionsSuccessBlock = successBlock;
283284
_restoreTransactionsFailureBlock = failureBlock;
284285
[[SKPaymentQueue defaultQueue] restoreCompletedTransactionsWithApplicationUsername:userIdentifier];
@@ -593,9 +594,13 @@ - (void)didFailTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQ
593594

594595
- (void)didRestoreTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQueue*)queue
595596
{
596-
RMStoreLog(@"transaction restored with product %@", transaction.originalTransaction.payment.productIdentifier);
597+
NSString *productIdentifier = transaction.originalTransaction.payment.productIdentifier;
598+
RMStoreLog(@"transaction restored with product %@", productIdentifier);
597599

598-
_pendingRestoredTransactionsCount++;
600+
if (productIdentifier)
601+
{
602+
[_pendingRestoredTransactionIds addObject:productIdentifier];
603+
}
599604
if (self.receiptVerifier != nil)
600605
{
601606
[self.receiptVerifier verifyTransaction:transaction success:^{
@@ -695,9 +700,14 @@ - (void)notifyRestoreTransactionFinishedIfApplicableAfterTransaction:(SKPaymentT
695700
if (transaction != nil)
696701
{
697702
[_restoredTransactions addObject:transaction];
698-
_pendingRestoredTransactionsCount--;
703+
704+
NSString *productIdentifier = transaction.payment.productIdentifier;
705+
if (productIdentifier)
706+
{
707+
[_pendingRestoredTransactionIds removeObject:productIdentifier];
708+
}
699709
}
700-
if (_restoredCompletedTransactionsFinished && _pendingRestoredTransactionsCount == 0)
710+
if (_restoredCompletedTransactionsFinished && _pendingRestoredTransactionIds.count == 0)
701711
{ // Wait until all restored transations have been verified
702712
NSArray *restoredTransactions = [_restoredTransactions copy];
703713
if (_restoreTransactionsSuccessBlock != nil)

0 commit comments

Comments
 (0)