{"id":1781,"url":"https://github.com/robotmedia/RMStore","last_synced_at":"2025-08-02T04:32:37.579Z","repository":{"id":9790820,"uuid":"11766695","full_name":"robotmedia/RMStore","owner":"robotmedia","description":"A lightweight iOS library for In-App Purchases","archived":false,"fork":false,"pushed_at":"2019-06-23T17:58:41.000Z","size":11667,"stargazers_count":2422,"open_issues_count":93,"forks_count":450,"subscribers_count":96,"default_branch":"master","last_synced_at":"2025-07-11T21:50:03.195Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robotmedia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-07-30T14:14:39.000Z","updated_at":"2025-07-04T06:13:33.000Z","dependencies_parsed_at":"2022-07-11T19:50:36.833Z","dependency_job_id":null,"html_url":"https://github.com/robotmedia/RMStore","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/robotmedia/RMStore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robotmedia%2FRMStore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robotmedia%2FRMStore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robotmedia%2FRMStore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robotmedia%2FRMStore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robotmedia","download_url":"https://codeload.github.com/robotmedia/RMStore/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robotmedia%2FRMStore/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268334618,"owners_count":24233793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:15:55.668Z","updated_at":"2025-08-02T04:32:35.693Z","avatar_url":"https://github.com/robotmedia.png","language":"C","funding_links":[],"categories":["Payments","IOS 或 OSX","Networking","OOM-Leaks-Crash"],"sub_categories":["Other Parsing","Other free courses","Payment"],"readme":"#RMStore\n\n[![CocoaPods Version](https://cocoapod-badges.herokuapp.com/v/RMStore/badge.png)](http://cocoadocs.org/docsets/RMStore) [![Platform](https://cocoapod-badges.herokuapp.com/p/RMStore/badge.png)](http://cocoadocs.org/docsets/RMStore)\n[![Build Status](https://travis-ci.org/robotmedia/RMStore.png)](https://travis-ci.org/robotmedia/RMStore)\n[![Join the chat at https://gitter.im/robotmedia/RMStore](https://badges.gitter.im/robotmedia/RMStore.svg)](https://gitter.im/robotmedia/RMStore?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nA lightweight iOS library for In-App Purchases.\n\nRMStore adds [blocks](#storekit-with-blocks) and [notifications](#notifications) to StoreKit, plus [receipt verification](#receipt-verification), [content downloads](#downloading-content) and [transaction persistence](#transaction-persistence). All in one class without external dependencies. Purchasing a product is as simple as:\n\n```objective-c\n[[RMStore defaultStore] addPayment:productID success:^(SKPaymentTransaction *transaction) {\n    NSLog(@\"Purchased!\");\n} failure:^(SKPaymentTransaction *transaction, NSError *error) {\n    NSLog(@\"Something went wrong\");\n}];\n```\n\n##Installation\n\nUsing [CocoaPods](http://cocoapods.org/):\n\n```ruby\npod 'RMStore', '~\u003e 0.7'\n```\n\nOr add the files from the [RMStore](https://github.com/robotmedia/RMStore/tree/master/RMStore) directory if you're doing it manually.\n\nCheck out the [wiki](https://github.com/robotmedia/RMStore/wiki/Installation) for more options.\n\n##StoreKit with blocks\n\nRMStore adds blocks to all asynchronous StoreKit operations.\n\n###Requesting products\n\n```objective-c\nNSSet *products = [NSSet setWithArray:@[@\"fabulousIdol\", @\"rootBeer\", @\"rubberChicken\"]];\n[[RMStore defaultStore] requestProducts:products success:^(NSArray *products, NSArray *invalidProductIdentifiers) {\n    NSLog(@\"Products loaded\");\n} failure:^(NSError *error) {\n    NSLog(@\"Something went wrong\");\n}];\n```\n\n###Add payment\n\n```objective-c\n[[RMStore defaultStore] addPayment:@\"waxLips\" success:^(SKPaymentTransaction *transaction) {\n    NSLog(@\"Product purchased\");\n} failure:^(SKPaymentTransaction *transaction, NSError *error) {\n    NSLog(@\"Something went wrong\");\n}];\n```\n\n###Restore transactions\n\n```objective-c\n[[RMStore defaultStore] restoreTransactionsOnSuccess:^(NSArray *transactions){\n    NSLog(@\"Transactions restored\");\n} failure:^(NSError *error) {\n    NSLog(@\"Something went wrong\");\n}];\n```\n\n###Refresh receipt (iOS 7+ only)\n\n```objective-c\n[[RMStore defaultStore] refreshReceiptOnSuccess:^{\n    NSLog(@\"Receipt refreshed\");\n} failure:^(NSError *error) {\n    NSLog(@\"Something went wrong\");\n}];\n```\n\n##Notifications\n\nRMStore 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`.\n\n###Adding and removing the observer\n\n```objective-c\n[[RMStore defaultStore] addStoreObserver:self];\n...\n[[RMStore defaultStore] removeStoreObserver:self];\n```\n\n###Products request notifications\n\n```objective-c\n- (void)storeProductsRequestFailed:(NSNotification*)notification\n{\n    NSError *error = notification.rm_storeError;\n}\n\n- (void)storeProductsRequestFinished:(NSNotification*)notification\n{\n    NSArray *products = notification.rm_products;\n    NSArray *invalidProductIdentifiers = notification.rm_invalidProductIdentififers;\n}\n```\n\n###Payment transaction notifications\n\nPayment transaction notifications are sent after a payment has been requested or for each restored transaction.\n\n```objective-c\n- (void)storePaymentTransactionFinished:(NSNotification*)notification\n{\n    NSString *productIdentifier = notification.rm_productIdentifier;\n    SKPaymentTransaction *transaction = notification.rm_transaction;\n}\n\n- (void)storePaymentTransactionFailed:(NSNotification*)notification\n{\n    NSError *error = notification.rm_storeError;\n    NSString *productIdentifier = notification.rm_productIdentifier;\n    SKPaymentTransaction *transaction = notification.rm_transaction;\n}\n\n// iOS 8+ only\n\n- (void)storePaymentTransactionDeferred:(NSNotification*)notification\n{\n    NSString *productIdentifier = notification.rm_productIdentifier;\n    SKPaymentTransaction *transaction = notification.rm_transaction;\n}\n```\n\n###Restore transactions notifications\n\n```objective-c\n- (void)storeRestoreTransactionsFailed:(NSNotification*)notification;\n{\n    NSError *error = notification.rm_storeError;\n}\n\n- (void)storeRestoreTransactionsFinished:(NSNotification*)notification\n{\n\tNSArray *transactions = notification.rm_transactions;\n}\n```\n\n###Download notifications (iOS 6+ only)\n\nFor Apple-hosted and self-hosted downloads:\n\n```objective-c\n- (void)storeDownloadFailed:(NSNotification*)notification\n{\n    SKDownload *download = notification.rm_storeDownload; // Apple-hosted only\n    NSString *productIdentifier = notification.rm_productIdentifier;\n    SKPaymentTransaction *transaction = notification.rm_transaction;\n    NSError *error = notification.rm_storeError;\n}\n\n- (void)storeDownloadFinished:(NSNotification*)notification;\n{\n    SKDownload *download = notification.rm_storeDownload; // Apple-hosted only\n    NSString *productIdentifier = notification.rm_productIdentifier;\n    SKPaymentTransaction *transaction = notification.rm_transaction;\n}\n\n- (void)storeDownloadUpdated:(NSNotification*)notification\n{\n    SKDownload *download = notification.rm_storeDownload; // Apple-hosted only\n    NSString *productIdentifier = notification.rm_productIdentifier;\n    SKPaymentTransaction *transaction = notification.rm_transaction;\n    float progress = notification.rm_downloadProgress;\n}\n```\n\nOnly for Apple-hosted downloads:\n\n```objective-c\n- (void)storeDownloadCanceled:(NSNotification*)notification\n{\n\tSKDownload *download = notification.rm_storeDownload;\n    NSString *productIdentifier = notification.rm_productIdentifier;\n    SKPaymentTransaction *transaction = notification.rm_transaction;\n}\n\n- (void)storeDownloadPaused:(NSNotification*)notification\n{\n\tSKDownload *download = notification.rm_storeDownload;\n    NSString *productIdentifier = notification.rm_productIdentifier;\n    SKPaymentTransaction *transaction = notification.rm_transaction;\n}\n```\n\n###Refresh receipt notifications (iOS 7+ only)\n\n```objective-c\n- (void)storeRefreshReceiptFailed:(NSNotification*)notification;\n{\n    NSError *error = notification.rm_storeError;\n}\n\n- (void)storeRefreshReceiptFinished:(NSNotification*)notification { }\n```\n\n##Receipt verification\n\nRMStore 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.\n\nBoth options are outlined below. For more info, check out the [wiki](https://github.com/robotmedia/RMStore/wiki/Receipt-verification).\n\n###Reference verifiers\n\nRMStore 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](https://github.com/robotmedia/RMStore/tree/master/RMStore/Optional) into your project and set the verifier delegate (`receiptVerifier`) at startup. For example:\n\n```objective-c\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\n{\n    const BOOL iOS7OrHigher = floor(NSFoundationVersionNumber) \u003e NSFoundationVersionNumber_iOS_6_1;\n    _receiptVerifier = iOS7OrHigher ? [[RMStoreAppReceiptVerifier alloc] init] : [[RMStoreTransactionReceiptVerifier alloc] init];\n    [RMStore defaultStore].receiptVerifier = _receiptVerifier;\n    // Your code\n    return YES;\n}\n```\n\nIf security is a concern you might want to avoid using an open source verification logic, and provide your own custom verifier instead.\n\n###Custom verifier\n\nRMStore delegates receipt verification, enabling you to provide your own implementation using  the `RMStoreReceiptVerifier` protocol:\n\n```objective-c\n- (void)verifyTransaction:(SKPaymentTransaction*)transaction\n                           success:(void (^)())successBlock\n                           failure:(void (^)(NSError *error))failureBlock;\n```\n\nCall `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.\n\nYou will also need to set the `receiptVerifier` delegate at startup, as indicated above.\n\n##Downloading content\n\nRMStore automatically downloads Apple-hosted content and provides a delegate for a self-hosted content.\n\n###Apple-hosted content\n\nDownloadable 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.\n\nRMStore 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.\n\n###Self-hosted content\n\nRMStore delegates the downloading of self-hosted content via the optional `contentDownloader` delegate. You can provide your own implementation using the `RMStoreContentDownloader` protocol:\n\n```objective-c\n- (void)downloadContentForTransaction:(SKPaymentTransaction*)transaction\n                              success:(void (^)())successBlock\n                             progress:(void (^)(float progress))progressBlock\n                              failure:(void (^)(NSError *error))failureBlock;\n```\n\nCall `successBlock` if the download is successful, `failureBlock` if it isn't and `progressBlock` to notify the download progress. RMStore will consider that a transaction has finished or failed only after the content downloader delegate has successfully or unsuccessfully downloaded its content.\n\n##Transaction persistence\n\nRMStore delegates transaction persistence and provides two optional reference implementations for storing transactions in the Keychain or in `NSUserDefaults`. You can implement your transaction, use the reference implementations provided by the library or, in the case of non-consumables and auto-renewable subscriptions, get the transactions directly from the receipt.\n\nFor more info, check out the [wiki](https://github.com/robotmedia/RMStore/wiki/Transaction-persistence).\n\n\n##Requirements\n\nRMStore requires iOS 5.0 or above and ARC.\n\n##Roadmap\n\nRMStore is in initial development and its public API should not be considered stable. Future enhancements will include:\n\n* [Better OS X support](https://github.com/robotmedia/RMStore/issues/4)\n\n##License\n\n Copyright 2013-2014 [Robot Media SL](http://www.robotmedia.net)\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobotmedia%2FRMStore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobotmedia%2FRMStore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobotmedia%2FRMStore/lists"}