[ Silence ]
Good morning and welcome to the session about using StoreKit for In-App purchases.
So ... [Applause] Thank you.
So why are we even sitting here in this room?
Well, because more and more apps are switching to In-App purchases.
In fact, when I was making the slides on June 2nd, it was shocking.
An amazing 96 percent of the top 25 top grossing iPhone apps in the U.S. were using In-App purchases.
Of course that number has changed every day and today it dropped embarrassingly to a miserable like 88 percent.
So apps are switching and we want to better support them.
And we made a bunch of changes, and we'd like to share them with you today.
So first we'll talk about the changes that we made to to StoreKit and then we'll review the In-App purchase process and highlight the changes that you might want to make, and also discuss a few of the options and decisions, and the APIs you might want to use, as well.
Then we'll demystify the test environment because it's really important to use it.
Then we'll have a grab-bag of tips straight from the app review team to make sure you can pass the app review with flying colors.
So first, what's new in StoreKit?
So at the core, StoreKit is a payment system.
It possesses transactions and for every single transaction, it hands the application a receipt and the security of the whole model comes from the receipt.
And if there's only one thing you remember from today, is that the security is in the receipt.
So you can decide to make this as safe as possible as you want to.
You can really choose the safety level.
If your accountant warrants it, you can do very, very secure and you can do whatever what with it, but in the end, the security is in the receipt.
And it's not very difficult to verify receipts, but there's a bunch of details you want to get right.
So we spun off a separate session called, "Using Receipts to Protect Your Digital Sales," in Presidio at 2:00 p.m. You'll learn all the tools, the technique s, the APIs to verify the receipt and all the options you have.
So I very much recommend that you attend that session.
Now, let's take a step back and look at the history of the receipt.
In 2009, IOS introduced In-App purchases and for every In-App purchase, we give you a receipt and it was up to the application to store it and manage it.
And then in 2011, the OS X added the Mac App Store and threw in a new receipt in this ecosystem.
It's the app purchase receipt.
It's a proof of purchase for the application itself.
So when we added enough purchases to the Mac App Store, we decided to unite all these receipts into one big unified receipt.
And today, I'm very excited to announce that iOS is switching to the same unified receipt, which proved to be so successful.
[applause] So, thank you.
I'm glad you appreciate that.
So, it's the same receipt format for iOS 7 and OS X.
It is managed for you by StoreKit, which means we store it in the [inaudible] system and we give you an API to access it anytime you want to check it.
And you can now validate that receipt just like OS X on the device, which means you don't need your own servers anymore.
[Applause and cheering] Some people have implemented that, I see.
And there's another bonus.
This receipt contains the orange box, the app purchase receipt and you can use this for two things.
First, if you want this extra level of security, if you to make sure your application has been really paid for, then you can check this receipt and make sure has been purchased on this device and everything is legit.
But it also helps you if want to transfer to the premium level where the application is free and you sell the content.
How's that possible?
So say your application is stocked in the store as a paid application and at some point in time, you want to make this application a free application.
The problem is that when the user restores to a new device, you have no idea when they purchased the application.
So did they purchase the paid version or the free version?
So you don't know what content they're entitled to.
So, if you look into the app purchase receipts, you'll find a purchase date and this will allow you to know if your user is entitled to content, or if the user purchased after you switched to premium.
Now of course, we are talking about transition, which means that we have the old style receipts around and to be very clear, they are duplicated.
But fear not, your existing apps will continue to work, of course.
Even, in fact, if you take your existing code and you rebuild it against the iOS 7 SDK, the application will continue to work.
You'll still get your receipts, but you'll get a bunch of duplication warnings.
And I'm sure you got the you heard distinctive slide about 93 percent of the applications, of the users having updated to the latest version of the iOS.
That means people will transition to iOS 7.
And that means it's high time to transition it's time to start transitioning to a new receipt style.
But in the meantime, you probably want to support both the old style and new style of receipts and the right way to do this is not to check for the OS version, it is to use weak linking so you only keep the two good paths around and you want to check if your main bundle responds to the selector for the new API added to access a receipt.
Next is Volume Purchase Program.
We're adding a new licensing model here.
If you opt into this program then you are allowing large-volume purchasers, think large companies, think universities, think schools.
You're allowing them to buy your application in bulk and then for a school to assign licenses to the students.
And when the school year ends, the school can take the licenses back from the students and assign them to the new batch of students.
So that really unlocks the education market and the large enterprise market for applications.
Now if you look at it from a device point of view, when the school year ends and the students walk away, the school will revoke will revoke the licenses.
This will start a 30-day grace period during which the students can still launch the application and they can back up their documents and whatever they want.
They are warned about this.
But then when the 30-days the 30-day grace period expires, the license becomes revoked.
And on iOS, when the license is revoked, iOS will prevent the launch of the application.
And instead of launching, it will display dialog to explain the situation and offer the students to buy the application to keep using it.
OS X has a different security model.
On OS X your application will have to launch, discover it is expired, and then exit with a special code so that the finder can display this dialog and offer people to buy your applications.
But again, the security is in the receipt.
So in both cases, it is the application's responsibility to check the receipt and enforce and make sure the application stops running if the if it is expired.
And to do this, we added new fields in receipts.
So we've just touched the surface.
If you want to know more about this volume purchasing program, you can watch a video of the session that happened yesterday about extending your applications for enterprise and education.
And also you can attend the session in Presidio at 2:00 p.m.
about validating the receipts, which will tell you everything about the new fields we added to the receipts.
Next, hosted In-App purchases can now be free.
And what that really means is, you can use them for to distribute message content that all the user's need.
So think like musical instruments, or you know musical samples not navigation packages, anything that's huge and that you have to distribute to the same users.
You can use host in-app purchases.
You can upload this to the Apple server and Apple will host this, Apple will serve it, and Apple will even download it in the background for re-application, so it's very convenient.
In fact, many applications, that's' the only reason they had servers, to back their applications.
If that's the case, you don't need servers anymore, so its way simpler.
But keep in mind that they are In-App purchases so they still you know, the user still has to buy them, although it's for free, and authenticate.
And they still have to go through the app review process, but they're a very convenient way to distribute some content.
Now, let's review the four types of In-App purchases we have in the Apple ecosystem.
On the one end of the spectrum, we have consumable products.
It's for things like gold coins, things you can buy multiple times, but every time StoreKit hands it only once through the application and the application takes over and manages the amount of remaining gold coins or whatever it is.
And because it's managed by your application, StoreKit does not restore it to past devices because you're managing it.
Now on the other end of the spectrum, we have non-consumable products and it's for things like magazines, things that when you buy them, you own then forever.
And those are completely managed through StoreKit and StoreKit will will restore them across devices and manage them completely.
Now since we're talking about magazines, if you are dealing with periodicals then you can use the auto-renewable subscriptions.
And those what a user really buys is a period of time.
The user buys a period of time, a subscription period and when that period finishes, [inaudible] store will automatically renew the subscription period and drop a transaction into the device payment queue.
So it's, again, managed by StoreKit.
And you also have the option to provide a free subscription period to the users in exchange for them opting in to share in their personal data with you.
And the data from the field shows that a majority of people actually trust your applications and trust your brands, so they opt in to share the data.
Now, for all the other types of time-based In-App purchases, you should use non-renewing subscriptions.
You can view them conceptually as consumables because the user when the user purchases them they're only handed once to the application and the application takes over and manages the subscription in whatever way that makes sense for the application.
So it is extremely flexible.
You can do any kind of subscription model here.
But sorry in fact, it is so flexible that it has no duration information inside the purchase object.
It is really up to you to implement it the way a way that's meaningful to your application.
So that's typically used typically used for things like access to fly charts the latest fly charts, access to financial services, all the professional apps.
Now if you summarize, iOS supports all four types of in-app purchases.
OS X supports only consumables and non-consumables.
And as you've probably guessed, today we're excited to bring subscriptions to OS X Mavericks.
So the first question we expect is how can they make that content available on both platforms?
And the answer is you can, but the product and identifiers are separate in OS X and iOS.
So you will have to use your own account management, track the subscription on one platform, and make the content available on the other platform, and that wraps the updates for In-App purchases.
Now, let's go through the In-App purchase process and let's highlight the few changes you'll have to make to transition to new receipts.
And also on the way we'll make a bunch of stops, and we'll discuss all the options you have, all the APIs you can use to deal with the content and all the issues connected to In-App purchases.
So I'm going to assume here that you already know the basics of StoreKit and that you probably have an application to store and an iOS application running.
Now if you don't, I will gladly point you to the [inaudible] on the website, and to the introductory session we had last year that you can watch a video for on the website.
So what do we need to make an In-App purchase process?
We need really three large phases.
First you have to set up the products in Action Connect and if it's hosting In-App purchases, if you have content, you want to package your content inside of Xcode.
Then the user can make the purchase on the client the device or the Mac, and when purchase happens you want to verify receipts and you can do this either on the client or on the server.
So let's assume here that you have set up your [inaudible] already.
So when the user wants to sorry, the In-App purchase process is this long process of stages and the first thing you want to do is figure out what you want to sell.
And you really have two major options here.
If you have In-App purchases like game options, things just unlocking the game, then you can just bake the identifiers into your application.
That's perfectly fine.
Now, if you have if you're sending content like magazines or comics, then you probably want to fetch your identifier from your server so that it can be very dynamic.
So we know what we want to sell now, but now we have to fetch the information about the product to display to the user.
And to do this, you first want to create a set of identifiers and then with a set of identifiers, you can create a StoreKit products request.
You want to add yourself as delegate to request and start the request.
And that's all there is to do and the request will be sent to the server.
And when it comes down from the server with a response, your delegate will fire with either fire with error because the device was may be offline, not very interesting but you still have to handle it or if you're online that's a good case, you will get, "Did receive response."
And the response will contain two things.
The first thing is invalid product identifiers.
It's the unlucky case where you ask for information of the product that is not in the store anymore and that could be because maybe you removed from the store Action Connect, or maybe you just didn't make it available in this specific country for any kind of reason.
So, it's a case to keep in mind, but in most of the cases, the product is valid and you will get a product rating response.
So, that production rating contains StoreKit products.
And each of those has all the attributes you want to use to display the to display the contents.
So, you'll find a title localized in the country of the store accounts.
You'll find the description localized for the same country.
You'll find a price in the currency of the store accounts and you'll find the locale, which contains the currency.
And if it's a hosted In-App purchase, well you'll also get the content size and the content version.
And you can use this information for things like offering the user to upgrade to a new version or just telling then they're up to date.
So there's one question we get very often.
How do you display the product price?
And it's difficult, dollar goes in to franc, Euros goes in the back, where does the Yen go, and then you have decimal separators.
So the best way to deal with this is to be super lazy.
And we have this class in the system called NSNumberFormatter.
And if you create one of those and you said it's style to be a currency style, and you set it's locale to be the locale you got from the product response, then all you have to do is go string from number with the price you got from the store and this gives you a string that you can display to the user.
So it's pretty simple.
What you should really not do is try to do any kind of currency conversion because the price the store gives you and the price currency that the store gives you is what we will charge to the user.
So it is the price that should be displayed to the user.
So that's the best way to do it, just display the price as is and get help for formatting the price with the unit and all these kinds of things.
Now we have information and now it's time to kind of expose the user to the goods.
You want to show the in-app purchase you are to the user.
And this is completely up to the application.
Why? Well, because only you know your application.
Only you know your content.
Only you can actually present it in a way that does it justice, in a way that's attractive, that fits the game play, or the application style.
So it's something that's worth investing some time and effort in to get it right because when you get it right, it has a huge impact.
It shows dramatically on the sales numbers.
So for example, if you're selling comics then you want to build a comic store, a gorgeous comic store.
This is comiXsology.
Look at that, it has a 99 cent specials.
It has [inaudible] Sprint.
It is attractive.
You can browse.
You can discover.
It has all the features you want to have in a real comic store.
Now if you're a game and your currency is like, you know, gold coins, then again you want to display these gold coins in a way that fits your application, in a way that fits the game play, so at the right moment in the game so that people are in the right mood and they don't feel like they're pressured to buy.
This is Heyday.
It's a free application yet its number three it's the third top grossing application today.
So that really shows that when you do it right, it works.
So let's assume here that you do it right, because why else would you do it, and make the purchase.
So the user has clicked this bag of coins and you want to make the purchase.
So to do this you want to create a StoreKit payment object with the product you get from the product response, and then you add this payment to the payment queue, and that's all you have to do.
StoreKit will take over.
StoreKit will start the dialog to ask the user to authenticate, and then StoreKit will also ask the user to make sure they really want to buy this bag of coins.
And if the user says buy, StoreKit will send the payment request up to the server.
So I'm going to interrupt the smooth flow here and open a parenthesis about irregular activity.
So Apple has an advanced engine to discover irregular activity and block it before it even happens and that's the best case.
But there's cases where we can't detect it before it happens so we can't block it.
So the purchases go through and then we have to we will eventually detect it anyway so we'll have to refund the customer.
We'll have to pull back the function developers and that tarnishes everybody's reputation; tarnishes ours and your application's name might be associated to the scheme.
So it is in our our interests are aligned.
It is in our interest to block the activity as much as possible.
So here's one case where we're going to be asking for your collaboration.
Imagine three devices are making In-App purchases with three different three different Apple IDs.
There's really nothing suspicious here.
There could be three, could be dozens.
That's what the story's about.
Its millions of devices making millions of purchases with millions of Apple IDs, so it's really hard to block this kind of activity when it's fraudulous.
But now if I tell you, "Oh, all these devices are buying gold coins and all these devices are crediting those gold coins to the same game account," then suddenly that picture becomes highly suspicious.
And it's something that, if you help us, we can detect and block.
And to do this, we've added API in StoreKits for you to provide us with an opaque account identifier.
So let's be very clear.
It has to be an opaque identifier.
That means we don't want to know your account names or users.
We really don't want to know about this.
The only thing we want to be able to do is in fact if multiple devices are making purchases for the same game accounts, so it has to be opaque.
It has to be your user account.
So don't give us the Apple ID, we know this already.
Don't give us your account's name; we don't want to know the account's name.
That's really your business, not ours.
Don't give us the password, obviously.
What we suggest you do is hash the account name so that gives you that gives us an opaque identifier that's going to be the same across devices yet will not allow us to identify your accounts.
And to do this, when you create your payment object, you only have to set the application username property to be that hash of user accounts.
So let's close this in unpleasant parenthesis and go back to the In-App purchase process.
So you have issued the purchase and the store will be processing it, and it will come back to the device as a transaction.
So you will be informed, because your payment queue server will be invoked with data transactions and you'll receive no change all in array of transactions.
The first thing it will do usually is eat right through those.
For each transaction you want to check and examine the transaction state.
If the state is purchased it means the transaction succeeded.
So, so far, you are accessing the old style receipt by calling the receipt property of the transaction and this is changing.
Now, the new way to access the receipt is to call app store receipt URL on your main bundle, and this gives you a URL to the receipt in the [inaudible] system and then you can load it with your favorite NSData methods.
So that's the only change you have to do to get to new receipts.
And once you have the receipts, you want to verify it.
And again, you choose the level of security you want to implement.
You can do it as simple as you want or as strong as you want.
You can verify on the device, that's the Mac or the phone, or you can verify on your server.
And if you're the kind of extremely cautious person, you can check on both, as well.
So, first option evaluating the receipt on the clients.
It is the preferred method.
It is the exact same validation as you have been doing iOS X.
It is exactly as secure.
And because in-app purchases have receipts all the time, you can access the receipt any time, even outside of the purchase process.
So if you have a comics application and user navigates to a comic to read it, that might be the right moment to go check the receipt for the comic to make sure that the user actually purchased the comic.
So you can do this any time and because it's local, of course it works offline.
Now the other solution is to evaluate the receipt on your own servers.
In that solution you want to first open a secure connection to your server and send a receipt up to your server, and then your server can turn around and forward the receipts to the Apple validation servers.
And what the evaluation servers do is they crack open the receipts and they return a pay load, adjacent pay load, easy two parts, that contains all the fields of the receipts and results go to tell you oh that receipt is valid.
So then your server can process that.
In addition, if you are dealing with auto-renewable subscriptions, your server can send a shared secret to the Apple validation servers and that will tell the Apple validation servers that "oh, if the transaction auto-renewed I'm sorry if the subscription was renewed then the Apple validation server will return the renewed receipt to the server."
And that's very important because that means the server can manage the subscription complete server side without the device being involved anymore.
And if you are a newsstand application it means the server can determine which issues to push to devices so it's very convenient.
So again, you want to validate the receipt of your server and you own the secure connect.
You only keep it secured as needed so of course we recommend you use SSL, extended verification certificates, certificate pinning, whatever you want to do to ensure you're talking to your own server and the content hasn't been tampered with.
As we saw it's great for auto renewable subscriptions because you can move all the subscription logic server side.
But the downside is because you're talking to a server, you have to be online so the application has to be aware that if it's offline it will have to deal with the case.
Now, what you should absolutely never do is check the receipt from your application directly against the Apple validation servers.
Why is that?
Well, you don't own both ends of the transaction of the connection so you can't make that connection secure, that means you can't trust it.
And if you're dealing with subscriptions then you will have to embed your shared secret into your application, which is kind of fragile.
And you want to send it across a connection that you really know you can trust.
So that's two, actually three reasons not to do this.
And again, validating receipt is not very hard, but you have to get it right and there's a bunch of APIs and tools you can use to help you with this.
So again, I'm going to refer you to the session in Presidio at 2:00 PM to learn all the, you know, ins and outs of receipt validation.
All right, so we have determined that the receipt is valid and now it's time to deliver the goods because the user paid for them.
So there's five choices here.
If you just have to unlock something in your application like a weapon, then just unlock it, that's very easy.
Now, if you want to download digital content then you have four APIs you can use.
You can use host In-App purchases as we saw earlier.
We can use newsstand kit for periodicals.
In iOS 7 we're adding a new API to download contents in the background and you can also use the legacy classic downloads.
So first, host In-App purchases.
They are just regular In-App purchases with content associated.
So it comes from the Apple servers.
That's great because if the application becomes an overnight hit, which I honestly wish it would happens, you won't have to scramble to buy servers and bandwidth overnight and try to kind of, you know, face all the server downtime and these issues because Apple will serve these In-App purchases, these host In-App purchases and we'll scale them necessarily.
And also because they're downloaded through StoreKit and StoreKit's a background API, they will continue downloading in the background, as well.
And they are in-app purchases so they go through review.
And there's one limit to those.
It's that you can only have I mean each In-App purchase can only be up to two gigabytes in size.
You can have as many products as you want, but each of them has to be is limited to two gigabytes.
So quick overview how the API works so you can know what to look for in the future, when you get when you're payment of server fires with updates to transactions, if a transaction is associated with a host In-App purchase, the transaction will have an array of downloads.
And to start them you can just tell the payment cues to start the downloads with this array, and then the downloads will start, and as they progress your payment queue server will fire with update downloads.
And each of these download objects in the array you will find a progress, you'll find the time remaining, you'll find the state and if things go wrong, you'll find the error.
When the state reaches download state finished then you can access another property called content URL that tells you where the file landed in the file system so you can access it.
Now, if you're dealing with periodicals you have another option.
You can use Newsstand Kit downloads.
Newsstand Kits downloads from your own server to your application in the background and gives you a fine-grain control of the credentials and authentication.
And the bonus that Newsstand Kit offers is that when the download finishes, the application gets woken up so it has a chance to look at the file and updates its icon in the Newsstand folder to be the latest cover.
So again, high level overview of the API.
It all starts with a Newsstand Kit library.
And when you want to download something, you want to first add a Newsstand Kit issue with a name and a date that you can get from the direct response.
Then you want to wrap the download URL into an [inaudible] recall subject.
And with this subject, you can create Newsstand Kit asset download object.
So if you followed the library contains the issues and the issues contain Asset downloads.
So when you're ready to download, you can just scroll down to the delegates on the download, and this will begin to download and this make your object the delegate, so it will get informed whenever that makes progress or finishes downloading.
So we mentioned that Newsstand Kits was downloading in the background.
So potentially the application could exit and then launch again.
So the question is how does the application reconnect to downloads that have been progressing in the background.
Well, the Newsstand Kit library, again, is the starting point.
It keeps it maintains for you, a list of the downloading assets so you can access this list when you launch your application and for each of those, we call the same method, download with delegates.
This will reconnect you to download, make your object the delegate, and all the delegate methods will fire exactly as the application and never go into the background.
So it's very simple, but it's only for periodicals.
Now, in iOS 7 we've added a new API to download in the background.
So it's only iOS, it lets you download from your own servers.
It lets you download in foreground and in the background, and you can control the authentication pretty precisely.
And an added benefit is its power efficient.
So as long as the application is in the foreground, then the content is urgent, we'll get it as fast as possible.
But if the user backgrounds the application, then maybe that content isn't that urgent anymore, so iOS will use its best judgment to find the appropriate moments to download this without draining the battery.
So again, a high level overview of the API.
To initiate the download, you first want to create an NSURL session configuration object and we have a factory method for this that creates one for you that is pre-configured to continue in the background.
And all you give it is an identifier that's going to be very useful for reconnecting when the application launches again.
And then the real object you want to create is an NSURL session and you can create this with a configuration object.
You give it your object as a delegate and you can give it the delegate cue so that you know what cue the delegate methods will fire on, very convenient for multithreading.
So again, you want to wrap your URL into a URL request object and you want to create an NSURL session download task.
That's an object that as soon as you create it, will start downloading into temporary file location.
And because you are the delegates, your delegate methods will fire every time there's progress so didWriteData is the right place to compute the progress and display to the user.
When the download finishes you'll get didFinishDownloading to your URL and this will give you the URL of the place the download [inaudible] in.
Usually the first thing you want to do there is access the file and copy to a safe place.
And again, this application downloads in the background so you have to be able to reconnect to the downloads, and it's very easy with this application.
It happens at the UI application delegate level.
So the UIApplication protocol go to new method and your application delegates.
When the application launches, we'll get called with handle events with background URL session.
This will give you the identifier for the session that just that you have to reconnect to and a completion handler.
So you want to use the same code to recreate the session and this will reconnect you to the session.
And because you passed your objects as delegates your delegate methods will start firing again exactly as if the application had never been put in the background so very convenient, very simple.
Once all the delegate methods are finished firing and you finish processing and updating the UI and do all that you have to do, you only call the completion handler.
So for now the best thing you can do is store it somewhere so you can use it later.
So we just scratched the surface of the API and it has many more bounties to offer.
So if you want to know more of this API download new background then you're welcome to watch a session about the Foundation Networking session the video from the session that happened yesterday.
And finally, you can keep using the legacy download APIs, but it's not a good idea, actually because when the application gets backgrounded, the download stops so that means you know this.
Your user is stuck looking at a progress bar and user is afraid to exit the app.
User's afraid to do anything because it will stop the download.
So it's not the best experience.
Now of course some applications use begin background task and they use it to get some background time to finish downloading, but it was never meant for doing downloads.
In fact, in iOS 7, begin background tasks has changed semantics.
It no longer prevents the device from sleeping.
So you will get your 10 minutes, but maybe not right now.
Maybe you'll get them when the iPod touch has left the home and has no Wi-Fi connection anymore.
So for downloads, not a very good experience.
So we recommend that you use the other options now that we have really good options.
And finally you have the [inaudible] assets and the final step is to finish this transaction.
Again, not change here.
You have to finish the transaction by calling finish transaction.
And it's the right thing to do, but if you don't do it, it's actually terrible.
If you don't do it, the end finish transactions will stack up and you have all this backlog and every time you launch your application StoreKit will notify your payment queue server every single application launch of every single unfinished transaction, and this slows down your app.
So, for the user's user's stuck waiting, it's not great, but also StoreKit will have to talk to the server to confirm the transactions.
So if user is on cellular you will incur some cellular data consumption.
So there's no point in doing this.
So it's very simple to just finish the transactions.
And that concludes the in-app purchase process overview.
So there's one best practice I'd like to mention.
To get your delegate method's goal you have to install the payment cube server.
And you guys are already doing this, but don't wait to make a purchase to install it.
You have to do it right when the application launches because as soon as the application launches, it may receive transaction any time.
Classic example, you try to make a you try to make a transaction and you lost the connection.
So transaction will have completed when the application was not running anymore.
So the next time you launch it, you will find the transaction.
You should process it; otherwise, the user has lost some content.
The user might have received a gift code and redeemed that gift code inside the app store.
And when the user launches the application, they expect that gift to be there so you have to process it as soon as the application launches.
And if you do periodicals then when you launch the application, the subscription might have renewed and you want to take this into account.
So as soon as you get app, you know, as soon as you get app did finish launching, it's the right moment to install the payment cube server.
And finally, for real, restoring in-app purchases nothing changes except the API you call to get the receipt so no change here.
And that wraps our kind of quick over flight of the in-app purchase process.
Now I'd like to discuss and demystify the test environment because it's something that's a very powerful tool.
It's something you should really use to make sure your in-app purchases behave correctly.
So today I'm going to call it SendBox, but it's not to be confused with the other SendBox, the one that limits access to your application resources.
So SendBox today means the test environment of the app store.
So the app store has a production environment and its evil twin, the SendBox.
So when the application is talking to the store they can be talking to either the SendBox or the production store.
How do you determine which one is very simple?
It's based on the certificate that was used for signing your application.
So when you develop your application it is signed with the development certificate.
So the OS would point your application to the production store sorry, to the SendBox.
Development hit SendBox.
Now, if your application is signed with app store certificates and the only way this could happen is if the user downloads the application from the app store, then the OS will point it to the production store.
And if you're ever unsure because you've messed up some accounts or something, just make internet purchase because you'll hear this dialog and if you see this line, it means you're hitting the SendBox.
So what's the main difference?
First of all, the SendBox does not charge you, which is great because you want to test as much as possible.
And yeah, you can laugh.
And if you get a SendBox receipt is it not backed by a financial transaction, therefore, it will not validate against the production store validation servers.
So you can feel free to use the SendBox.
These receipts will not validate against production.
And if you want to implement the Volume Purchase Program, then we mentioned that the receipt will contain new fields.
And we have API in the SendBox to request a receipt that's either expired or revoke so that the application can test how it behaves when licenses are expired or revoked.
And of course, if you get a revoked receipt from SendBox, iOS will not prevent your application from launching.
Otherwise, you could never test your code.
And the final thing to know about SendBox is that it makes time fly faster, for real.
This is great if you do subscriptions.
The rule of thumb is that one year becomes one hour, so a yearly subscription renews every hour and it will renew six times, and stop renewing so you can test your code for renewing subscriptions and you can test your code when a subscription stops renewing.
So in practice, that means you have to first log into Access Connect, create a test user, test users are not valid in the production store, there are two different sets, it's a source of confusion.
Its two different sets of users.
Then you want to create a product.
You want to build your app and you want to sign it.
And on the Mac there's one extra step.
On the Mac you have to launch the application once from the finder, and when the application detects there's no receipt and exits with the magic code, the finder will intercept this magic code and fetch a receipt for the application and relaunch it.
That is how you get a receipt on the Mac the first time.
If you launch the application from Xcode and the application exists with a magic code, the Xcode will just like intercept this and submit, and nothing will happen.
So launch the first time in the finder.
That's a very frequent, you know, kind of head-scratching case.
And that's all you have to do.
Next thing is just buy products, as much as you can.
So, to summarize, when you're developing the application is signed by your development certificate.
So the OS will point it to the SendBox and you can get a SendBox receipt and forward it to your own test server.
And your test server will let you get that receipt against the SendBox.
So, things just work.
Once the application is live in the store, it is signed by the store so if the production application, you will hit the production store.
You will get production receipts, you will form those production servers and you'll validate against the production store, everything works.
Now there's one case you really have to be aware of because it affects app review.
During app review, your application comes from the store.
So it is production signed.
But the reviewers don't want to charge anyone for reviewing.
So they will point the application to SendBox.
So your production application might get a SendBox receipt and forward it to your own production servers.
And if the server tries to validate that against the Apple production validation servers, it will fail, and you don't want this to fail because this will fail at review.
So, what we recommend to do, is to have your service first try to validate the receipts in the production environments and if it fails with the area code 21007, pretty easy to remember, then you want to turn back, and fall back, and hit the SendBox validation servers.
And if you do this, you'll pass the review easily.
So, talking about the app review, I'd like to finish with some feedback from the app review team but make no mistake, we want your application to pass that review.
We want them to be in the store.
We want them to have a great user experience and we want them to have a consistent user experience especially when transactions are involved.
You want that to be super clear to the user so they all have to be hit the same.
If they don't be hit the same, then the use the user's going to be confused.
They'll be confused, they'll like hesitate, they'll be fearful and that's something we'd like to leave the to competition.
So the first thing you have to do is have a restore button.
If you have non-consumables, you want to have a restore button.
If you don't and the user restores the application to new device, they have no way of restoring the content they paid for.
So they have lost content.
It's a terrible user experience.
So if you don't have a restore button, the application will get rejected.
And another misconception, restoring purchases is a free process.
You get a new device, you install the application, restore the purchases.
It's free; it's to get your content back.
The purchase process is to get new content and pay for it.
It's really different processes.
And you want this to be very clear for the user and so they have to be separate buttons.
No need to merge them.
If you are a news stand application, as we mentioned, you can give an incentive for people to share their personal data.
Otherwise, this is an automatic rejection.
Also you want to make it very clear to the user what they subscribe to, even before they purchase the app, so you want to put the subscription information directly into the marketing text.
We have a schedule in the application store guidelines that you can use for this.
And free subscriptions it's okay to use them.
In fact, we love them but they are for free stuff.
They should not be used as a way to get people to subscribe to a temporary promotion and then you raise the price.
In fact, if you try to do this, it will fail because the moment you raise the price, the store will stop renewing because the users haven't agreed to the new price.
So, free subscriptions are for free publications.
And even though they're free, that doesn't mean you can auto enroll the user or subscribe the user because the user still should be in control of the content that goes into the devices.
So even a free subscription, they should have a subscribe button.
And in Newsstand, it is totally okay, in fact it's great if you offer the users the option to purchase individual issues of the magazines.
But you also have to have the option to subscribe to the magazine because that's what Newsstand is all about.
It's having content magically delivered to your device when you and it's there when you wake up.
So if you are not a Newsstand app, but you do auto renewal subscriptions, it's almost the same case.
You have to give the users an idea of what they're going to be subscribing to.
So you have to put the subscription information inside the marketing text.
And you have to think about what happens to the user if they subscribe.
So when the user subscribes, you know, they pay some money.
They should get something.
The latest issue should become downloaded or even downloaded automatically.
But what you shouldn't do is have the user subscribe and then nothing happens.
They should get some content.
Again, paid subscriptions, they're totally fine but they're offered paid contents.
You can't ask the user to pay for things he could get for free otherwise.
And apps that do services, professional apps, they usually they should use their flexibility of non-renewing subscriptions.
And talking about the non-renewing subscriptions, it is okay to ask user to register but it should be optional.
That is, users can use your app and if you want to track them, offer to register.
They can register if they want to, that's great.
Don't make it compulsory unless your application has features that users can only get through accounts you know, through their accounts.
And the final word is about purchases.
They just must work because the app review team will make purchases and if the purchases don't work, they can't approve the application.
So purchases have to work and that's why we have this test environment.
That's why we ask that you test your purchases as much as possible.
And the best way to pass app review easily is also the best way to get good user feedback and read reviews and loyalty.
And it's also the best way to get great sales is to have a clean, easy to understand, simple, entertaining, pleasant, and above all, rock solid user experience.
And that's all I have for you today.
So if you have any questions, feel free to talk to our evangelist Paul Marcos.
We have updated the Commentator Developer websites and the Apple Developer Forum are a good place to ask look around and ask a bunch of questions.
Thanks for using StoreKits.
[ Applause ]
[ Silence ]