Need help with CargoManager?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

127 Stars 9 Forks BSD 2-Clause "Simplified" License 45 Commits 2 Opened issues


The Essential StoreKit/CargoBay Companion

Services available


Need anything else?

Contributors list

# 36,130
40 commits

NEW: Check out the CargoManager Example iOS App.


Implement StoreKit easily

is an open source library that helps you implement IAPs for iOS apps in a simple and encapsulated way by using the by using the delegate pattern.

is the Apple framework for making In-App Purchases. It's pretty good but it is very low level and has a few rough edges.
is really nifty, but it keeps coding of In-App Purchases quite at a low level and it still is an involved process.

abstracts most details of StoreKit and CargoBay by providing a simple and pretty much automated manager for your In-App Purchases.

With CargoManager you only have to implement two protocols in your own classes. You will need to set these objects as CargoManager delegates: - An object conforming to the

protocol. This delegate is mandatory. It provides all available Product ID strings to CargoManager (which in turn caches the returned products for store population). It also should respond to successful transaction events by providing the user requested content and storing it persistently to disk. Ideally, this delegate should be a singleton and should be alive at all times (a transaction is kept as pending even after relaunching the game, so it can complete even when you are not looking at the store UI). - An object conforming to the
protocol. This delegate is optional. It should update the UI on both transaction successful and transaction failed events (if you create a modal "processing IAP screen" you can dismiss it by using this delegate).

Please note that before attempting to use

it is strongly recommended that you fully understand how StoreKit works. The In-App Purchase Programming Guide by Apple provides a concise and gentle introduction.

In addition to the protocols, you will need to call these provided methods:

// Call this method after setting the contentDelegate
// it setups CargoManager to work with CargoBay and
// launches the initial product request.
- (void)loadStore;

// Get a product from the cached products.

  • (SKProduct *)productForIdentifier:(NSString *)identifier;

// Start an In-App purchase.

  • (void)buyProduct:(SKProduct *)product;


provides the following properties:
@property (nonatomic, readonly) BOOL productRequestDidReceiveResponse;
@property (nonatomic, readonly) BOOL productRequestError;
and also sends the
notification after it caches the products. These are needed because if you enter the store quick enough after the app launches, the initial product request will not have resolved from Apple servers yet, so you won't be able to populate item prices. Instead, you can observe this notification to populate your store UI as soon as they load (you can do that even having the store UI open in your app, as to not artificially delay the user entering the store).

Last but not least, CargoManager includes a category for Apple's SKProduct, which provides the following

@property (nonatomic, readonly) NSString *localizedPrice;
which returns the product price formatted as a currency string in the user locale.


Initial setup

// Your AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    // Initialize CargoManager (you have to implement the contentDelegate first!).
    [CargoManager sharedManager].contentDelegate = [GameData sharedData];

// This call sends a product request to CargoBay and caches the resulting products.
[[CargoManager sharedManager] loadStore];

return YES;


contentDelegate sample implementation

// contentDelegate should be a singleton object available at all times through the lifetime of your app
- (NSArray *)productIdentifiers
    NSMutableArray *productIdentifiers = [[NSMutableArray alloc] init];

// Populate the productIdentifiers.

// Return a non-mutable copy.
return [NSArray arrayWithArray:productIdentifiers];


  • (void)provideContentForProductIdentifier:(NSString *)productIdentifier { // Implement the result of a successful IAP // on the according productIdentifier. // YOUR CODE GOES HERE

    // Save user data to disk. // YOUR CODE GOES HERE }

UIDelegate sample implementation

// UIDelegate is optional. Normally, it will be your StoreViewController.
  • (void)transactionDidFinishWithSuccess:(BOOL)success { if ( success ) {

      // Close store UI ?

    } else {

      // Do not close the store ? Further notify the user about the error?


  • // You can respond to the CMProductRequestDidReceiveResponseNotification in the following manner.

    • (void)viewDidLoad { [super viewDidLoad];

      [[NSNotificationCenter defaultCenter] addObserver:self

                                               object:[CargoManager sharedManager]];


    CargoManagerContentDelegate protocol specification

    @protocol CargoManagerContentDelegate 

    // This method should return an array with all the productIdentifiers used by your App.

    • (NSArray *)productIdentifiers;

    // Implement this method to provide content.

    • (void)provideContentForProductIdentifier:(NSString *)productIdentifier;


    // Use this method if you want to store the transaction for your records.

    • (void)recordTransaction:(SKPaymentTransaction *)transaction;

    // Use this method to manage download data.

    • (void)downloadUpdated:(SKDownload *)download;


    CargoManagerUIDelegate protocol specification

    @protocol CargoManagerUIDelegate 

    // Implement this method to update UI after a IAP has finished. // This method is called both for successful and failed transactions.

    • (void)transactionDidFinishWithSuccess:(BOOL)success;


    // Implement this method to update UI after a IAP restore has finished. // This method is called both for successful and failed restores.

    • (void)restoredTransactionsDidFinishWithSuccess:(BOOL)success;



    CargoManager is used by Trivia Pics Party!.

    If your app and company uses CargoManager and want it listed here, just drop me a line.

    License & Contact

    CargoManager is available under the FreeBSD license so you can use it for commercial applications. See the LICENSE file for more info.

    It is maintained by Ricardo Sánchez-Sáez (rsanchez.saez [at] gmail [dot] com).

    We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.