SCPStoreKitManager
Block based store kit manager for In-App Purchase on iOS 7, 8 & 9 with receipt validation.
Install / Use
/learn @steprescott/SCPStoreKitManagerREADME
SCPStoreKitManager 
Block based store kit manager for In-App Purchase for iOS 7, 8 & 9 with receipt validation. Please note that you must have iTunes Connect set up correctly with some IAPs already. The example App has no visual feed back to the user but you can follow it's progress via the console. The app can only work on a iDevice and can not be ran in a simulator.
Required frameworks
- StoreKit
Installation
Pod
SCPStoreKitManager is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'SCPStoreKitManager'
Please note if you want to include the receipt validation part of this manager then you need to tell CocoaPods that you want the validation subspec by adding the following line instead of the snippit above :
pod 'SCPStoreKitManager/SCPStoreKitReceiptValidator'
Also note the receipt validator uses OpenSSL and compiles the static libary when you run pod install. This can take up to 15 minutes to complete.
Submodule
- Add this repo as a submodule or download it as a .zip
- Within the folder named
srcthere is the required files in the folder namedSCPStoreKitManager. If you don't wish to validate receipts then only copy theCategoriesfolder and theSCPStoreKitManager.h + .minto your project. - Looking to your Project Navigator right mouse click on the
SCPStoreKitManagerfolder and click show in finder. This should open up a new finder window to the location where you have the framework saved. - Navigating to the project build settings of your project, in the
Search Pathssection you need to add a path to the headers and libs. To do this double click on the Header Search Paths item. This should bring up a pop over. Going back to your finder window we opened in step 3 press and hold little folder next to the title of the finder window and drag it into the Header Search Paths popover. - You should see something like
"$(SRCROOT)/ExampleProject/SCPStoreKitManager". You must now change the drop down value in the last column fromnon-recursivetorecursive. Click away to save this. - Now double clicking on the Library Search Paths a similar popover should show. Going back to the finder window, navigate to
SCPStoreKitReceiptValidator > openSSL > lib. Again with thelibfolder selected press and hold the little folder next to the finder window title and drag it into the Library Search Paths popover. - Just like we did in step 5 you should see something like
"$(SRCROOT)/ExampleProject/SCPStoreKitManager/SCPStoreKitReceiptValidator/openSSL/lib". Click away to save this.
NOTE : If you want to use your own implementation of OpenSSL then link these search paths to point to your implementation.
You should now be able to build the project and get no errors. If you do have errors, ensure that both search paths are set to recursive.
Usage
The framework is split into two parts. The first is to retrieve the In-App purchases from iTunes and handle the purchase of them. The second is receipt validation. You do not need to use the receipt validation but it is advised to protect your IAPs.
SCPStoreKitManager
This is a nice block based wrapper round StoreKits delegate methods.
There are four instance methods that are to accessed via the shared instance.
- (void)requestProductsWithIdentifiers:(NSSet *)productsSet productsReturnedSuccessfully:(ProductsReturnedSuccessfully)productsReturnedSuccessfullyBlock invalidProducts:(InvalidProducts)invalidProductsBlock failure:(Failure)failureBlock;
This method takes a NSSet of product identifiers. These product identifiers should match the Product ID of the IAP that you have set up in iTunes Connect. If you need help with this look at the Apple Documentation
This requests the IAP details for each product you ask for and upon a successful request it will call the success block returning an NSArray of SKProduct. If you have requested a product that is not on iTunes Connect then these identifiers will be returned as an NSArray of NSString of the identifiers that failed.
The failure block will catch any other errors such as no connectivity to iTunes.
Example
//Request the product details from iTunes
[[SCPStoreKitManager sharedInstance] requestProductsWithIdentifiers:productIdentifiers
productsReturnedSuccessfully:^(NSArray *products) {
NSLog(@"Products : %@", products);
}
invalidProducts:^(NSArray *invalidProducts) {
NSLog(@"Invalid Products : %@", invalidProducts);
}
failure:^(NSError *error) {
NSLog(@"Error : %@", [error localizedDescription]);
}];
- (void)requestPaymentForProduct:(SKProduct *)product paymentTransactionStatePurchasing:(PaymentTransactionStatePurchasing)paymentTransactionStatePurchasingBlock paymentTransactionStatePurchased:(PaymentTransactionStatePurchased)paymentTransactionStatePurchasedBlock paymentTransactionStateFailed:(PaymentTransactionStateFailed)paymentTransactionStateFailedBlock paymentTransactionStateRestored:(PaymentTransactionStateRestored)paymentTransactionStateRestoredBlock failure:(Failure)failureBlock;
This method takes a SKProduct that you wish to request payment for. There are four blocks that are called depending on the state of the SKProduct transaction. The use of these blocks is to allow you to update your UI along the process of taking payment. Each of these blocks with the exception of the failure block return an NSArray of SKPaymentTransaction. When the paymentTransactionStatePurchased block is called Apple has taken payment for the products that are returned in the transactions array. At this point you should unlock or add what is needed to honour the purchase.
Example
//Request payment for product
[[SCPStoreKitManager sharedInstance] requestPaymentForProduct:_products[indexPath.row]
paymentTransactionStatePurchasing:^(NSArray *transactions) {
NSLog(@"Purchasing products : %@", transactions);
}
paymentTransactionStatePurchased:^(NSArray *transactions) {
NSLog(@"Purchased products : %@", transactions);
}
paymentTransactionStateFailed:^(NSArray *transactions) {
NSLog(@"Failed products : %@", transactions);
}
paymentTransactionStateRestored:^(NSArray *transactions) {
NSLog(@"Restored products : %@", transactions);
}
failure:^(NSError *error) {
NSLog(@"Failure : %@", [error localizedDescription]);
}];
- (void)restorePurchasesPaymentTransactionStateRestored:(PaymentTransactionStateRestored)paymentTransactionStateRestoredBlock paymentTransactionStateFailed:(PaymentTransactionStateFailed)paymentTransactionStateFailedBlock failure:(Failure)failureBlock;
If you offer IAP you must provide a way for any IAP made to be restored More info. To do this call this method on the shared instance and all previous transactions will be returned to the PaymentTransactionStateRestored block in an NSArray of SKPaymentTransaction.
Example
//Request to restore previous purchases
[[SCPStoreKitManager sharedInstance] restorePurchasesPaymentTransactionStateRestored:^(NSArray *transactions) {
NSLog(@"Restored transactions : %@", transactions);
}
paymentTransactionStateFailed:^(NSArray *transactions) {
NSLog(@"Failed to restore transactions : %@", transactions);
}
failure:^(NSError *error) {
NSLog(@"Failure : %@", [error localizedDescription]);
}];
- (NSString *)localizedPriceForProduct:(SKProduct *)product;
Method that takes a SKProduct and returns a NSString of the price for the product that matches the phones locale.
Example
[productPriceLabel setText:[[SCPStoreKitManager sharedInstance] localizedPriceForProduct:product]];
SCPStoreKitReceiptValidator
- (void)validateReceiptWithBundleIdentifier:(NSString *)bundleIdentifier bundleVersion:(NSString *)bundleVersion tryAgain:(BOOL)tryAgain showReceiptAlert:(BOOL)showReceiptAlert alertViewTitle:(NSString *)alertViewTitle alertViewMessage:(NSString *)alertViewMessage success:(Success)successBlock failure:(Failure)failureBlock;
One method that validates the app receipt is from Apple Inc and has not been tampered with. This method does take a few arguments but I b
