Skip to content
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

Optimize SKPayment #213

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
4 changes: 3 additions & 1 deletion RMStore/RMStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ extern NSInteger const RMStoreErrorCodeDownloadCanceled;
extern NSInteger const RMStoreErrorCodeUnknownProductIdentifier;
extern NSInteger const RMStoreErrorCodeUnableToCompleteVerification;

extern NSString *const RMStoreNotificationExtraUserInfo;

/** A StoreKit wrapper that adds blocks and notifications, plus optional receipt verification and purchase management.
*/
@interface RMStore : NSObject<SKPaymentTransactionObserver>
Expand Down Expand Up @@ -217,7 +219,7 @@ extern NSInteger const RMStoreErrorCodeUnableToCompleteVerification;
@param failureBlock Called if the transaction failed verification. If verification could not be completed (e.g., due to connection issues), then error must be of code RMStoreErrorCodeUnableToCompleteVerification to prevent RMStore to finish the transaction. Must be called in the main queu.
*/
- (void)verifyTransaction:(SKPaymentTransaction*)transaction
success:(void (^)())successBlock
success:(void (^)(id successData))successBlock
failure:(void (^)(NSError *error))failureBlock;

@end
Expand Down
55 changes: 34 additions & 21 deletions RMStore/RMStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
NSString* const RMStoreNotificationTransaction = @"transaction";
NSString* const RMStoreNotificationTransactions = @"transactions";

NSString* const RMStoreNotificationExtraUserInfo = @"extraData";

#if DEBUG
#define RMStoreLog(...) NSLog(@"RMStore: %@", [NSString stringWithFormat:__VA_ARGS__]);
#else
Expand Down Expand Up @@ -199,18 +201,24 @@ - (void)addPayment:(NSString*)productIdentifier
success:(void (^)(SKPaymentTransaction *transaction))successBlock
failure:(void (^)(SKPaymentTransaction *transaction, NSError *error))failureBlock
{
SKMutablePayment *payment = nil;
SKProduct *product = [self productForIdentifier:productIdentifier];
if (product == nil)
{
RMStoreLog(@"unknown product id %@", productIdentifier)
if (failureBlock != nil)
{
NSError *error = [NSError errorWithDomain:RMStoreErrorDomain code:RMStoreErrorCodeUnknownProductIdentifier userInfo:@{NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Unknown product identifier", @"RMStore", @"Error description")}];
failureBlock(nil, error);
payment = [SKMutablePayment paymentWithProductIdentifier:productIdentifier];
if (payment == nil) {
RMStoreLog(@"unknown product id %@", productIdentifier)
if (failureBlock != nil)
{
NSError *error = [NSError errorWithDomain:RMStoreErrorDomain code:RMStoreErrorCodeUnknownProductIdentifier userInfo:@{NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Unknown product identifier", @"RMStore", @"Error description")}];
failureBlock(nil, error);
}
return;
}
return;
} else {
payment = [SKMutablePayment paymentWithProduct:product];
}
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];

if ([payment respondsToSelector:@selector(setApplicationUsername:)])
{
payment.applicationUsername = userIdentifier;
Expand Down Expand Up @@ -484,7 +492,7 @@ - (void)didFinishDownload:(SKDownload*)download queue:(SKPaymentQueue*)queue
const BOOL hasPendingDownloads = [self.class hasPendingDownloadsInTransaction:transaction];
if (!hasPendingDownloads)
{
[self finishTransaction:download.transaction queue:queue];
[self finishTransaction:download.transaction queue:queue extraData:nil];
}
}

Expand Down Expand Up @@ -528,16 +536,16 @@ - (void)didPurchaseTransaction:(SKPaymentTransaction *)transaction queue:(SKPaym

if (self.receiptVerifier != nil)
{
[self.receiptVerifier verifyTransaction:transaction success:^{
[self didVerifyTransaction:transaction queue:queue];
[self.receiptVerifier verifyTransaction:transaction success:^(id successData){
[self didVerifyTransaction:transaction queue:queue extraData:successData];
} failure:^(NSError *error) {
[self didFailTransaction:transaction queue:queue error:error];
}];
}
else
{
RMStoreLog(@"WARNING: no receipt verification");
[self didVerifyTransaction:transaction queue:queue];
[self didVerifyTransaction:transaction queue:queue extraData:nil];
}
}

Expand Down Expand Up @@ -574,16 +582,16 @@ - (void)didRestoreTransaction:(SKPaymentTransaction *)transaction queue:(SKPayme
_pendingRestoredTransactionsCount++;
if (self.receiptVerifier != nil)
{
[self.receiptVerifier verifyTransaction:transaction success:^{
[self didVerifyTransaction:transaction queue:queue];
[self.receiptVerifier verifyTransaction:transaction success:^(id successData){
[self didVerifyTransaction:transaction queue:queue extraData:successData];
} failure:^(NSError *error) {
[self didFailTransaction:transaction queue:queue error:error];
}];
}
else
{
RMStoreLog(@"WARNING: no receipt verification");
[self didVerifyTransaction:transaction queue:queue];
[self didVerifyTransaction:transaction queue:queue extraData:nil];
}
}

Expand All @@ -592,13 +600,13 @@ - (void)didDeferTransaction:(SKPaymentTransaction *)transaction
[self postNotificationWithName:RMSKPaymentTransactionDeferred transaction:transaction userInfoExtras:nil];
}

- (void)didVerifyTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQueue*)queue
- (void)didVerifyTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQueue*)queue extraData:(id)extraData
{
if (self.contentDownloader != nil)
{
[self.contentDownloader downloadContentForTransaction:transaction success:^{
[self postNotificationWithName:RMSKDownloadFinished transaction:transaction userInfoExtras:nil];
[self didDownloadSelfHostedContentForTransaction:transaction queue:queue];
[self didDownloadSelfHostedContentForTransaction:transaction queue:queue extraData:extraData];
} progress:^(float progress) {
NSDictionary *extras = @{RMStoreNotificationDownloadProgress : @(progress)};
[self postNotificationWithName:RMSKDownloadUpdated transaction:transaction userInfoExtras:extras];
Expand All @@ -610,11 +618,11 @@ - (void)didVerifyTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymen
}
else
{
[self didDownloadSelfHostedContentForTransaction:transaction queue:queue];
[self didDownloadSelfHostedContentForTransaction:transaction queue:queue extraData:extraData];
}
}

- (void)didDownloadSelfHostedContentForTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQueue*)queue
- (void)didDownloadSelfHostedContentForTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQueue*)queue extraData:(id)extraData
{
NSArray *downloads = [transaction respondsToSelector:@selector(downloads)] ? transaction.downloads : @[];
if (downloads.count > 0)
Expand All @@ -624,11 +632,11 @@ - (void)didDownloadSelfHostedContentForTransaction:(SKPaymentTransaction *)trans
}
else
{
[self finishTransaction:transaction queue:queue];
[self finishTransaction:transaction queue:queue extraData:extraData];
}
}

- (void)finishTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQueue*)queue
- (void)finishTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQueue*)queue extraData:(id)extraData
{
SKPayment *payment = transaction.payment;
NSString* productIdentifier = payment.productIdentifier;
Expand All @@ -641,7 +649,12 @@ - (void)finishTransaction:(SKPaymentTransaction *)transaction queue:(SKPaymentQu
wrapper.successBlock(transaction);
}

[self postNotificationWithName:RMSKPaymentTransactionFinished transaction:transaction userInfoExtras:nil];
NSDictionary *extraInfo = nil;
if (extraData) {
extraInfo = @{RMStoreNotificationExtraUserInfo:extraData};
}

[self postNotificationWithName:RMSKPaymentTransactionFinished transaction:transaction userInfoExtras:extraInfo];

if (transaction.transactionState == SKPaymentTransactionStateRestored)
{
Expand Down