RMStore
A lightweight iOS library for In-App Purchases
Install / Use
/learn @robotmedia/RMStoreREADME
#RMStore
A lightweight iOS library for In-App Purchases.
RMStore adds blocks and notifications to StoreKit, plus receipt verification, content downloads and transaction persistence. All in one class without external dependencies. Purchasing a product is as simple as:
[[RMStore defaultStore] addPayment:productID success:^(SKPaymentTransaction *transaction) {
NSLog(@"Purchased!");
} failure:^(SKPaymentTransaction *transaction, NSError *error) {
NSLog(@"Something went wrong");
}];
##Installation
Using CocoaPods:
pod 'RMStore', '~> 0.7'
Or add the files from the RMStore directory if you're doing it manually.
Check out the wiki for more options.
##StoreKit with blocks
RMStore adds blocks to all asynchronous StoreKit operations.
###Requesting products
NSSet *products = [NSSet setWithArray:@[@"fabulousIdol", @"rootBeer", @"rubberChicken"]];
[[RMStore defaultStore] requestProducts:products success:^(NSArray *products, NSArray *invalidProductIdentifiers) {
NSLog(@"Products loaded");
} failure:^(NSError *error) {
NSLog(@"Something went wrong");
}];
###Add payment
[[RMStore defaultStore] addPayment:@"waxLips" success:^(SKPaymentTransaction *transaction) {
NSLog(@"Product purchased");
} failure:^(SKPaymentTransaction *transaction, NSError *error) {
NSLog(@"Something went wrong");
}];
###Restore transactions
[[RMStore defaultStore] restoreTransactionsOnSuccess:^(NSArray *transactions){
NSLog(@"Transactions restored");
} failure:^(NSError *error) {
NSLog(@"Something went wrong");
}];
###Refresh receipt (iOS 7+ only)
[[RMStore defaultStore] refreshReceiptOnSuccess:^{
NSLog(@"Receipt refreshed");
} failure:^(NSError *error) {
NSLog(@"Something went wrong");
}];
##Notifications
RMStore sends notifications of StoreKit related events and extends NSNotification to provide relevant information. To receive them, implement the desired methods of the RMStoreObserver protocol and add the observer to RMStore.
###Adding and removing the observer
[[RMStore defaultStore] addStoreObserver:self];
...
[[RMStore defaultStore] removeStoreObserver:self];
###Products request notifications
- (void)storeProductsRequestFailed:(NSNotification*)notification
{
NSError *error = notification.rm_storeError;
}
- (void)storeProductsRequestFinished:(NSNotification*)notification
{
NSArray *products = notification.rm_products;
NSArray *invalidProductIdentifiers = notification.rm_invalidProductIdentififers;
}
###Payment transaction notifications
Payment transaction notifications are sent after a payment has been requested or for each restored transaction.
- (void)storePaymentTransactionFinished:(NSNotification*)notification
{
NSString *productIdentifier = notification.rm_productIdentifier;
SKPaymentTransaction *transaction = notification.rm_transaction;
}
- (void)storePaymentTransactionFailed:(NSNotification*)notification
{
NSError *error = notification.rm_storeError;
NSString *productIdentifier = notification.rm_productIdentifier;
SKPaymentTransaction *transaction = notification.rm_transaction;
}
// iOS 8+ only
- (void)storePaymentTransactionDeferred:(NSNotification*)notification
{
NSString *productIdentifier = notification.rm_productIdentifier;
SKPaymentTransaction *transaction = notification.rm_transaction;
}
###Restore transactions notifications
- (void)storeRestoreTransactionsFailed:(NSNotification*)notification;
{
NSError *error = notification.rm_storeError;
}
- (void)storeRestoreTransactionsFinished:(NSNotification*)notification
{
NSArray *transactions = notification.rm_transactions;
}
###Download notifications (iOS 6+ only)
For Apple-hosted and self-hosted downloads:
- (void)storeDownloadFailed:(NSNotification*)notification
{
SKDownload *download = notification.rm_storeDownload; // Apple-hosted only
NSString *productIdentifier = notification.rm_productIdentifier;
SKPaymentTransaction *transaction = notification.rm_transaction;
NSError *error = notification.rm_storeError;
}
- (void)storeDownloadFinished:(NSNotification*)notification;
{
SKDownload *download = notification.rm_storeDownload; // Apple-hosted only
NSString *productIdentifier = notification.rm_productIdentifier;
SKPaymentTransaction *transaction = notification.rm_transaction;
}
- (void)storeDownloadUpdated:(NSNotification*)notification
{
SKDownload *download = notification.rm_storeDownload; // Apple-hosted only
NSString *productIdentifier = notification.rm_productIdentifier;
SKPaymentTransaction *transaction = notification.rm_transaction;
float progress = notification.rm_downloadProgress;
}
Only for Apple-hosted downloads:
- (void)storeDownloadCanceled:(NSNotification*)notification
{
SKDownload *download = notification.rm_storeDownload;
NSString *productIdentifier = notification.rm_productIdentifier;
SKPaymentTransaction *transaction = notification.rm_transaction;
}
- (void)storeDownloadPaused:(NSNotification*)notification
{
SKDownload *download = notification.rm_storeDownload;
NSString *productIdentifier = notification.rm_productIdentifier;
SKPaymentTransaction *transaction = notification.rm_transaction;
}
###Refresh receipt notifications (iOS 7+ only)
- (void)storeRefreshReceiptFailed:(NSNotification*)notification;
{
NSError *error = notification.rm_storeError;
}
- (void)storeRefreshReceiptFinished:(NSNotification*)notification { }
##Receipt verification
RMStore doesn't perform receipt verification by default but provides reference implementations. You can implement your own custom verification or use the reference verifiers provided by the library.
Both options are outlined below. For more info, check out the wiki.
###Reference verifiers
RMStore provides receipt verification via RMStoreAppReceiptVerifier (for iOS 7 or higher) and RMStoreTransactionReceiptVerifier (for iOS 6 or lower). To use any of them, add the corresponding files from RMStore/Optional into your project and set the verifier delegate (receiptVerifier) at startup. For example:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
const BOOL iOS7OrHigher = floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1;
_receiptVerifier = iOS7OrHigher ? [[RMStoreAppReceiptVerifier alloc] init] : [[RMStoreTransactionReceiptVerifier alloc] init];
[RMStore defaultStore].receiptVerifier = _receiptVerifier;
// Your code
return YES;
}
If security is a concern you might want to avoid using an open source verification logic, and provide your own custom verifier instead.
###Custom verifier
RMStore delegates receipt verification, enabling you to provide your own implementation using the RMStoreReceiptVerifier protocol:
- (void)verifyTransaction:(SKPaymentTransaction*)transaction
success:(void (^)())successBlock
failure:(void (^)(NSError *error))failureBlock;
Call successBlock if the receipt passes verification, and failureBlock if it doesn't. 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.
You will also need to set the receiptVerifier delegate at startup, as indicated above.
##Downloading content
RMStore automatically downloads Apple-hosted content and provides a delegate for a self-hosted content.
###Apple-hosted content
Downloadable content hosted by Apple (SKDownload) will be automatically downloaded when purchasing o restoring a product. RMStore will notify observers of the download progress by calling storeDownloadUpdate: and finally storeDownloadFinished:. Additionally, RMStore notifies when downloads are paused, cancelled or have failed.
RMStore will notify that a transaction finished or failed only after all of its downloads have been processed. If you use blocks, they will called afterwards as well. The same applies to restoring transactions.
###Self-hosted content
RMStore delegates the downloading of self-hosted content via the optional contentDownloader delegate. You can provide your own implementation using the RMStoreContentDownloader protocol:
- (void)downloadContentForTransaction:(SKPaymentTransaction*)transaction
success:(void (^)())successBlock
progress:(void (^)(float progress))progressBlock
failure:(void (^)(NSError *error))failureBlock;
Call successBlock if the download is successful, failureBlock if it isn't and progressBlock to notify the download progress. RMStore
Related Skills
node-connect
340.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
340.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.2kCommit, push, and open a PR



