Skip to content

Explicit transaction finish (RMStore/issues/151) #168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions RMStore/RMStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ extern NSInteger const RMStoreErrorCodeUnableToCompleteVerification;
/// @name Calling StoreKit
///---------------------------------------------

/**
This block should be called by a user in order to finish transaction
*/
typedef void (^RMStoreFinishTransactionBlock)();

/** Returns whether the user is allowed to make payments.
*/
+ (BOOL)canMakePayments;
Expand All @@ -63,7 +68,7 @@ extern NSInteger const RMStoreErrorCodeUnableToCompleteVerification;
@param failureBlock The block to be called if the payment fails or there isn't any product with the given identifier. Can be `nil`.
*/
- (void)addPayment:(NSString*)productIdentifier
success:(void (^)(SKPaymentTransaction *transaction))successBlock
success:(void (^)(SKPaymentTransaction *transaction, RMStoreFinishTransactionBlock finishBlock))successBlock
failure:(void (^)(SKPaymentTransaction *transaction, NSError *error))failureBlock;

/** Request payment of the product with the given product identifier. `successBlock` will be called if the payment is successful, `failureBlock` if it isn't.
Expand All @@ -75,7 +80,7 @@ extern NSInteger const RMStoreErrorCodeUnableToCompleteVerification;
*/
- (void)addPayment:(NSString*)productIdentifier
user:(NSString*)userIdentifier
success:(void (^)(SKPaymentTransaction *transaction))successBlock
success:(void (^)(SKPaymentTransaction *transaction, RMStoreFinishTransactionBlock finishBlock))successBlock
failure:(void (^)(SKPaymentTransaction *transaction, NSError *error))failureBlock __attribute__((availability(ios,introduced=7.0)));

/** Request localized information about a set of products from the Apple App Store.
Expand Down
21 changes: 14 additions & 7 deletions RMStore/RMStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
#endif

typedef void (^RMSKPaymentTransactionFailureBlock)(SKPaymentTransaction *transaction, NSError *error);
typedef void (^RMSKPaymentTransactionSuccessBlock)(SKPaymentTransaction *transaction);
typedef void (^RMSKPaymentTransactionSuccessBlock)(SKPaymentTransaction *transaction, RMStoreFinishTransactionBlock finishBlock);
typedef void (^RMSKProductsRequestFailureBlock)(NSError *error);
typedef void (^RMSKProductsRequestSuccessBlock)(NSArray *products, NSArray *invalidIdentifiers);
typedef void (^RMStoreFailureBlock)(NSError *error);
Expand Down Expand Up @@ -188,15 +188,15 @@ - (void)addPayment:(NSString*)productIdentifier
}

- (void)addPayment:(NSString*)productIdentifier
success:(void (^)(SKPaymentTransaction *transaction))successBlock
success:(void (^)(SKPaymentTransaction *transaction, RMStoreFinishTransactionBlock finishBlock))successBlock
failure:(void (^)(SKPaymentTransaction *transaction, NSError *error))failureBlock
{
[self addPayment:productIdentifier user:nil success:successBlock failure:failureBlock];
}

- (void)addPayment:(NSString*)productIdentifier
user:(NSString*)userIdentifier
success:(void (^)(SKPaymentTransaction *transaction))successBlock
success:(void (^)(SKPaymentTransaction *transaction, RMStoreFinishTransactionBlock finishBlock))successBlock
failure:(void (^)(SKPaymentTransaction *transaction, NSError *error))failureBlock
{
SKProduct *product = [self productForIdentifier:productIdentifier];
Expand Down Expand Up @@ -631,14 +631,21 @@ - (void)didDownloadSelfHostedContentForTransaction:(SKPaymentTransaction *)trans
- (void)finishTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQueue*)queue
{
SKPayment *payment = transaction.payment;
NSString* productIdentifier = payment.productIdentifier;
[queue finishTransaction:transaction];
[self.transactionPersistor persistTransaction:transaction];
NSString* productIdentifier = payment.productIdentifier;

RMStoreFinishTransactionBlock finishBlock = ^{
[queue finishTransaction:transaction];
[self.transactionPersistor persistTransaction:transaction];
};

RMAddPaymentParameters *wrapper = [self popAddPaymentParametersForIdentifier:productIdentifier];
if (wrapper.successBlock != nil)
{
wrapper.successBlock(transaction);
wrapper.successBlock(transaction, finishBlock);
}
else
{
finishBlock();
}

[self postNotificationWithName:RMSKPaymentTransactionFinished transaction:transaction userInfoExtras:nil];
Expand Down
6 changes: 5 additions & 1 deletion RMStoreDemo/RMStoreViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath

NSString *productID = [_products objectAtIndex:indexPath.row];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[[RMStore defaultStore] addPayment:productID success:^(SKPaymentTransaction *transaction) {
[[RMStore defaultStore] addPayment:productID success:^(SKPaymentTransaction *transaction, RMStoreFinishTransactionBlock finishBlock) {

// Finish transaction
finishBlock();

[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
} failure:^(SKPaymentTransaction *transaction, NSError *error) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
Expand Down
13 changes: 8 additions & 5 deletions RMStoreTests/RMStoreTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,11 @@ - (void)testAddPayment_UnknownProduct_Nil_Nil
- (void)testAddPayment_UnknownProduct_Block_Block
{
__block BOOL failureBlockCalled;
[_store addPayment:@"test" success:^(SKPaymentTransaction *transaction) {
[_store addPayment:@"test" success:^(SKPaymentTransaction *transaction, RMStoreFinishTransactionBlock finishBlock) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warc-retain-cycles"
XCTFail(@"Success block");
finishBlock();
#pragma GCC diagnostic pop
} failure:^(SKPaymentTransaction *transaction, NSError *error) {
failureBlockCalled = YES;
Expand Down Expand Up @@ -275,7 +276,7 @@ - (void)testPaymentQueueUpdatedDownloads_Empty
- (void)testPaymentQueueUpdatedDownloads_Active
{ SKIP_IF_VERSION(NSFoundationVersionNumber_iOS_5_1)
id download = [self mockDownloadWithState:SKDownloadStateActive];
[[[download stub] andReturnValue:OCMOCK_VALUE(0.5f)] progress];
[(SKDownload *)[[download stub] andReturnValue:OCMOCK_VALUE(0.5f)] progress];

id transaction = [self mockPaymentTransactionWithState:SKPaymentTransactionStatePurchased downloads:@[download]];
NSString *productID = [[transaction payment] productIdentifier];
Expand All @@ -288,7 +289,7 @@ - (void)testPaymentQueueUpdatedDownloads_Active
XCTAssertEqualObjects(download, returnedDownload);
XCTAssertEqualObjects(transaction, returnedTransaction);
XCTAssertTrue([productID isEqualToString:returnedProductID]);
XCTAssertTrue([download progress] == downloadProgress);
XCTAssertTrue([(SKDownload *)download progress] == downloadProgress);
return YES;
}]];
[_store addStoreObserver:_observer];
Expand Down Expand Up @@ -691,7 +692,8 @@ - (void)testPaymentQueueUpdatedTransactions_Purchased__NoVerifier_Blocks
id product = [OCMockObject mockForClass:[SKProduct class]];
[[[product stub] andReturn:@"test"] productIdentifier];
(_store.products)[@"test"] = product;
[_store addPayment:@"test" success:^(SKPaymentTransaction *transaction) {
[_store addPayment:@"test" success:^(SKPaymentTransaction *transaction, RMStoreFinishTransactionBlock finishBlock) {
finishBlock();
XCTAssertEqualObjects(transaction, originalTransaction, @"");
} failure:^(SKPaymentTransaction *transaction, NSError *error) {
XCTFail(@"");
Expand Down Expand Up @@ -926,7 +928,8 @@ - (void)testPaymentQueueUpdatedTransactions_Failed__Blocks
id product = [OCMockObject mockForClass:[SKProduct class]];
[[[product stub] andReturn:@"test"] productIdentifier];
(_store.products)[@"test"] = product;
[_store addPayment:@"test" success:^(SKPaymentTransaction *transaction) {
[_store addPayment:@"test" success:^(SKPaymentTransaction *transaction,RMStoreFinishTransactionBlock finishBlock) {
finishBlock();
XCTFail(@"");
} failure:^(SKPaymentTransaction *transaction, NSError *error) {
XCTAssertEqualObjects(transaction, originalTransaction, @"");
Expand Down