IAP Best Practices
This document is Apple's new Technical Note -- In-App Purchase Best Practices released In August 5. It describes IAP Best Practices In iOS and OS X applications.
The following is a list of IAP best practices recommended to developers.
Add a transaction queue observer when the application starts
The application calls StoreKit to link the observer to the payment queue.
- [SKPaymentQueue defaultQueue] addTransactionObserver:your_observer];
When you resume or run your app, StoreKit automatically notifies you of the changes to the content of the payment queue) the observer adds an observer when the application starts to ensure that it exists when all apps start. This will allow your application to receive all the payment queue reminders.
Considering the application, an observer is created for the DetailViewController class of the application before adding a payment request to the queue, such as table 1. The existence time of this observer is the same as that of the DetailViewController instance. If a network failure occurs, for example, the app cannot complete the purchase process, and the related transactions are still in the payment queue. After the app recovers, it does not have an observer because the observer is removed when the app is sent to the background. Therefore, your application will not receive transaction notifications in the queue.
List 1. Do not follow the best practices for implementing transaction observer: when a user attempts to buy a product, the application adds an observer for the payment queue:
- @implementation DetailViewController
- ....
-
- // Called when a customer attempts to purchase a product
- - (IBAction)purchase:(id)sender
- {
- // Register an observer to the payment queue
- [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
-
- // Create a payment request
- SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:self.product];
-
- // Submit the payment request to the payment queue
- [[SKPaymentQueue defaultQueue] addPayment:payment];
- }
- ....
- @end
List 2. Follow the best practices for registering transaction observers
- @implementation AppDelegate
-
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- // Attach an observer to the payment queue
- [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
- return YES;
- }
-
- // Called when the application is about to terminate
- - (void)applicationWillTerminate:(UIApplication *)application
- {
- // Remove the observer
- [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
- }
-
- ....
- @end
StoreKit removes the observer from the payment queue when calling the app:
Similarly, if the observer is not removed from the payment queue, StoreKit will attempt to notify the above observer, resulting in the application crash, as if the observer no longer exists.
Ask the App Store for product information before displaying the App Store UI.
Before deciding to display purchased items on the user interface, your application must first send a product request to the App Store. Sending a product request allows you to determine whether the product can be sold in the App Store to prevent the display of products that cannot be purchased. You can view Retrieving Product Information to learn how to create a Product request. App Store uses the SKResponse object to respond to product requests, and uses its products attribute to update your UI, so that your users can only see products available for sale in App Store.
List 3. Do not follow IAP product display best practices: after displaying a salable product, the APP asks the App Store for related product information.
- // App first displays a product for sale, then queries the App Store about it when a customer attempts to purchase it
- - (IBAction)purchase:(id)sender
- {
- // Create a set for your product identifier
- NSSet *productSet = [NSSet setWithObject:@"your_product_identifier"];
- // Create a product request object and initialize it with the above set
- SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:productSet];
-
- request.delegate = self;
- // Send the request to the App Store
- [request start];
- }
-
-
-
- // Get the App Store's response
- - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
- {
- // No purchase will take place if there are no products available for sale.
- // As a result, StoreKit won't prompt your customer to authenticate their purchase.
- if ([response.products count] > 0)
- {
- SKProduct *product = (SKProduct *)[response.products objectAtIndex:0];
-
- // The product is available, let's submit a payment request to the queue
- SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
- [[SKPaymentQueue defaultQueue] addPayment:payment];
- }
- }
List 4. Best practices for IAP Product Display
- -(void)fetchProductInformationForIds:(NSArray *)productIds
- {
- // Create a set for your product identifier
- NSSet *mySet = [NSSet setWithObject:your_product_identifier];
-
- // Create a product request object and initialize it with the above set
- SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:mySet];
-
- request.delegate = self;
-
- // Send the request to the App Store
- [request start];
- }
-
-
- //Get the App Store's response
- - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
- {
- if ([response.products count] > 0)
- {
- // Use availableProducts to populate your UI
- NSArray *availableProducts = response.products;
- }
- }
Provides a UI for restoring products
If your applications sell non-consumable, auto-renewable subgraphs, or non-renewing subgraphs, you must provide a UI that allows them to be restored. You can view Differences Between Product Types and Restoring Purchased Products for more information.
Transaction Processing
Call StoreKit to add a payment request for the payment queue:
- [[SKPaymentQueue defaultQueue] addPayment:your_payment];
The queue creates a transaction object to process this request. When the transaction status changes, StoreKit notifies your observer by calling paymentQueue: updatedTransactions.
In-App Purchase Programming Guide> Delivering Products> Table 4-1 Transaction statuses and corresponding actions list four possible Transaction States for each Transaction. Make sure that the observer's paymentQueue: updatedTransactions: can respond to these statuses at any time. If the IAP product is hosted by Apple, You need to implement paymentQueue: updatedDownloads: Method on the observer.
Provides paid content
When you receive a transaction in the SKPaymentTransactionStatePurchased or SKPaymentTransactionStateRestored state, the application will deliver content to the user or unlock the app function. These statuses indicate that you have received payment for the available products. Users also want the application to provide paid content.
If your purchased product includes App Store-hosted content, make sure to call SKPaymentQueue's startDownloads: download content. You can view Unlocking App Functionality and Delivering Associated Content for more information.
Complete delivery
Transactions are stored in the payment queue until they are removed. Each time an application is started or recovered from the background, StoreKit will call the observer's paymentQueue: updatedTransactions: until they are removed. Your users may repeatedly request to verify their purchases or be prevented from purchasing your products.
Call finishTransaction: remove the transaction from the queue. The completed transaction cannot be recovered. Therefore, you must provide the content, download all the content of apple-hosted products, or complete your purchase process before completing the transaction. View Finishing the Transaction for more information.
Test IAP implementation
Ensure that the IAP implementation is thoroughly tested before the application is submitted for review. You can view multiple test scenarios in Suggested Testing Steps and find various troubleshooting methods in Frequently Asked Questions.
Refer:
In-App Purchase Programming Guide
Adding In-App Purchase to your iOS and OS X Applications
WWDC 2012: Selling Products with Store Kit
WWDC 2012: Managing Subscriptions with In-App Purchase
WWDC 2013: Using Store Kit for In-App Purchases
WWDC 2014: Optimizing In-App Purchases
Link: http://www.cocoachina.com/applenews/devnews/2014/0818/9407.html