Unlocking Builtin Content

This method is by far the easiest route, requiring far fewer steps that can all be done from within your app. There's no need to maintain a server, and you don't have to worry about security issues when communicating between your app and server. Just a few interactions with the App Store and then purchased content is unlocked from within your app (see Figure 6-14).

Figure 6-14. The built-in In-App Purchase delivery model

Using this model requires all your related In-App Purchase content to already be embedded into the app, hidden away from users. When a customer purchases a particular item, your app simply unlocks access to it. This works great for providing integrated content such as new levels in a game or additional features in a productivity app or for activating subscription-based functionality.

Store Kit does not support any way to "patch" your app binary with a downloaded update from a remote server. If your app requires the purchased content to be integrated within the app bundle, then you should include it in your application before submitting it to the App Store. Then after a customer purchase, your app can simply unlock this content.

The easiest way for your app to record and remember unlocked content is to store the information in your app's preferences, which get backed up when users sync their devices with their computer via iTunes. Having the app's preferences backed up will help prevent purchases from being lost, even if the app gets deleted on a user's device. Your app needs to remember which items have already been purchased so that the next time the user runs your app, the purchased content is still readily accessible.

The one major drawback to using this built-in unlocking model is that if you decide to make additional In-App Purchase items available in the future, you'll need to submit a new, updated application binary to the App Store that includes the new content.

Downloading Content from Your Server

If you're constantly adding new In-App Purchase items for your application, then using the server download approach is the recommended route. This requires quite a few more steps and saddles you with a lot of server management responsibilities, but this model provides the most flexibility and future growth possibilities for your app (see Figure 6-15).

Figure 6-15. The server-based In-App Purchase delivery model

The Comics app by ComiXology (showcased earlier in this chapter) is a perfect example of this model. The app fetches the latest list of product IDs for available digital comics from the server. When a user purchases a specific digital comic book, the app then downloads the file from the server. The app can open and view any selected digital comic file from the user's downloaded collection of purchased issues.

This approach enables new digital comics to be made available every week as In-App Purchase items without requiring any updates to the actual Comics application. New In-App Purchase items are submitted for review through iTunes Connect, and when they're approved, ComiXology simply adds their product IDs to the database on their server. Then the next time the Comics app checks for new items, it retrieves the latest list of new digital comics from the ComiXology server.

You cannot "patch" your app binary with a downloaded app update from a remote server. If your app requires the purchased content to be integrated within the app bundle, then delivering purchased content from your server is not the appropriate path. You'll need to use the built-in model of embedding the content in your application before submitting it to the App Store. Then after a customer purchase, your app can simply unlock this content.

Ever plan on delivering the same content to more than just iPhone users? The server-based model is recommended if you allow customers to access their purchased content on multiple platforms, such as via the iPhone, an Android phone, a web browser, and so on. This way, all of the content and customer records can be easily managed in one central location (such as a database on your server) with all supported devices connecting to it.

The big drawback to delivering content from a remote server is that Store Kit does not provide any kind of infrastructure for communicating with your server. It's up to you to develop and implement your own custom server-side applications for interacting with your iPhone app.

The only thing the Store Kit does offer is a method for your server to verify a received transaction receipt. When your iPhone app notifies your server that a purchase was successfully completed, it needs to send a transaction receipt to the server. As you may remember, I mentioned that when an In-App Purchase transaction is finished, the App Store returns valuable transaction information to your application's transaction observer class. Before removing the completed transaction from the payment queue, you should first capture the transaction.payment.productIdentifier and the transaction.transactionReceipt. The productIdentifier property provides the product ID of the purchased item and the transactionReceipt property includes an encrypted receipt of the order. By sending this transaction receipt to your server, you've now given your server the data needed to verify and authorize the purchase. Without a valid receipt, this prevents hackers from tricking your server into granting free downloads of content that were never legitimately purchased.

Of course, you can't send this raw data in a URL query string, so you'll need to first Base64-encode the transaction receipt before sending it to your server. As I mentioned in Chapter 5, The iPhone SDK does not include Base64 encoding and decoding, but several third-party Objective-C libraries are available that provide Base64 support for iPhone, such as Google Toolbox for Mac (http://code.google.com/p7google-toolbox-for-mac/).

So, how does this verification process work? When your server receives the Base64-encoded string from your iPhone app, it should then submit the receipt data as a JavaScript Object Notation (JSON) dictionary directly to the App Store via an HTTP POST request:


If you're testing your app and server prior to public release, then receipt data should instead be sent to the App Store's test environment here:


If you're unfamiliar with JSON syntax, here's an example of how your post should be formatted:

"receipt-data" : "Your receipt data goes here"

The App Store will respond by returning a JSON dictionary to your server:

"receipt" : { ...Includes a list of keys with purchased product details... }

If the "status" key has a value of 0, then your receipt has been validated as a real App Store purchase. Now that the authenticity of the transaction has been confirmed, your server can safely authorize the download. The list of keys returned in the "receipt" key contains details about the purchased product, which your server can use to determine which specific content to deliver to your iPhone app.

This added verification layer is a good security mechanism to help prevent piracy. Although In-App Purchase makes it a little more difficult for hackers to crack the paid content within your app, nothing is bullet-proof. It's only a matter of time until they figure out how to bypass Apple's In-App Purchase verification scheme. If you produce popular software products, then unfortunately piracy will always be part of the equation. It's good to do what you can to prevent casual hackers, but it's really not worth obsessing over too much. If hackers want to crack your app, they'll find a way to do it. Even though a select handful of iPhone developers have reported dismal app piracy rates as high as 80 percent, that's not all money lost. A large percentage of those people using a cracked version would never have paid for your app anyway. Your time and energy is best invested in keeping your paying customers happy.

For the descriptions and syntax of those JSON-based receipt keys, please see Apple's Store Kit documentation in the iPhone SDK. To learn more about using JSON with various server-side languages, such as PHP or Ruby on Rails, check out the official JSON web site at http://www.json.org/.

If you're not an experienced web developer, then the prospect of creating custom web applications and server-side infrastructure for communicating with your iPhone app can seem overwhelming, to say the least. This server-based model also puts the burden of reliable scalability and security on your shoulders. If your app enjoys a large customer base, testing your server to withstand a lot of traffic and potential security threats is essential. Server-related problems affect not only the perceived performance quality of your iPhone app but also your business reputation (and liability).

Mobile Apps Made Easy

Mobile Apps Made Easy

Quick start guide to skyrocket your offline and online business success with mobile apps. If you know anything about mobile devices, you’ve probably heard that famous phrase coined by one of the mobile device’s most prolific creators proclaiming that there’s an app for pretty much everything.

Get My Free Training Guide

Post a comment