In the previous tutorial we have added a buy button and implemented the payment transaction. The next step is to provide the content that the user paid for. In our case we want to download some photos that are hosted on the Apple server.
Please note that hosting content on Apple’s server is not the only alternative. If the content you unlock by In-App Purchase is small then you can have it in the app bundle. This way the user doesn’t have to wait for any download to take place. However, if you include too much content in your app bundle, the initial download of the app takes too long and space is wasted for users that don’t purchase the IAP products. You should consider the advantages and disadvantages of each approach and choose the one that is most suitable.
In our example we are providing some photos as content. Depending on the number of products and the number of photos in each product we could end up with quite a large application bundle if we were to embed them. And hosting content on Apple’s server means we need to implement a bit more code and learn even more about the StoreKit payment queue and the transaction observer.
Configure products to host on Apple’s server
When we configured our In-App Purchase product in iTunes Connect we didn’t turn on hosting content with Apple. We need to do this now. So go to iTunes Connect, select the Photos app and go to the In-App Purchases section. If you select a product and scroll down a bit you should see something like this:
The message is pretty clear, so let’s edit the In-App Purchase Details and set “Hosting Content with Apple” to yes:
Save the changes and check again the “Hosting Content with Apple” section for the product. You should see something like this:
The status for your product is now “Waiting for Upload”, not “Ready to Submit”:
And if you run the app you will see that the product does not appear in the list of products. This is the reason why we didn’t enable this feature before. To have the status go back to “Ready to Submit” we need to upload the content to the Apple server.
Uploading content to the Apple server
From the message in iTunes Connect we know we need to upload content using the Application Loader. But what exactly does content mean? In the In-App Purchase Programming Guide we find the answer:
You create an Apple-hosted content bundle using the In-App Purchase Content target in Xcode and submit it to iTunes Connect.
So let’s add a new target to our project. Go to File -> New -> Target… and select the In-App Purchase one:
You will be asked for a name. I chose CatPhotos like the first product setup in iTunes Connect. And you have to make sure that you select the proper bundle ID. The bundle ID for my product is “com.masteringios.Photos”, not “com.masteringios” like it was suggested by Xcode.
You will notice that a new folder appeared in your project. This is where we can add our photos. You cannot add executable code in the product bundle, all the code needed for the app to run must be in the main application bundle. So in our case all that we’ll add to this folder are the cat photos. Let’s add them to our target:
My CatPhotos folder looks like this:
Let’s try and build this target. Select the target in Xcode and build it for any iPhone or iPad simulator:
This will fail because our target can only be built for a real device. If you connect you iOS device and try to build it again this time it should work. And because you have a device connected the “Archive” option from the Product menu will be active. So let’s create an archive for our target:
After the archive is ready check that its type is “In-App Purchase Content Archive”. If this is the case then you can “Export…” it as an Installer Package:
This will create a .pkg file that we can upload to iTunes Connect. Remember where you saved the file because you will need it later. Now let’s see how to use Application Loader to upload the package to iTunes Connect.
Using Application Loader to upload products
To open the Application Loader go to the menu and select Xcode, then Open Developer Tools and select Application Loader:
You will be presented with a Template Chooser window. Select New In-App Purchases. The next window will allow you to select the app, so choose the appropriate one. You should see something like this:
There are a lot of things that you can configure in this screen, but the thing we’re interested in is the Hosted Content. If you select Hosted Content you will see a “Host Content with Apple” checkbox and underneath an empty box for the hosted content package. Press the “Choose…” button and select the package we’ve created earlier.
Pressing Next will take you to the Delivery screen:
The package was validated correctly and is now ready to be delivered. Press “Deliver” and wait until all the necessary steps are completed.
Thanks for the incredible tutorial, it has helped me to implement IAP downloads on my app. Could you clarify how to access the downloaded content? I already have the path to it (download.contentURL), but I’m not sure how to access the files inside it.