2013 • 57:23
Join us for a deep dive into new technologies in iOS 7 that can enable you to reduce your app’s bundle size, keep your apps in communication with your server, and more. Gain valuable insights into best practices for building networked games. And protect your reputation by following best practices for security and privacy. Learn how to use these cutting edge iOS 7 technologies while still supporting users who haven't yet upgraded.
Speaker: Paul Marcos
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript was generated using Whisper, it may have transcription errors.
[Paul Marcos]
All right, welcome back. Welcome to Integrating iOS 7 System Technologies. My name is Paul Marcos, and I'm the App Services Evangelist at Apple. Now, obviously, we've been talking about all this great new technology in iOS 7, and there's a ton of it. And this is a pretty common slide and a pretty common scenario for us to be in, where every year we have a major release of iOS, and it brings just a whole lot of new functionality and APIs and great stuff for game developers and for app developers in general. But one of the challenges that I think you all face, and actually I was talking with some folks in the lab about this earlier today, is really making sense of how do you take this new technology and integrate it into your app? And what pieces are most important to you and how do you actually take that technology and use it in a meaningful way? And that's how I want to talk about a couple new pieces of technology here and really put it in the context of some very specific user experiences that people have in your games and in apps and how you can apply some of this new technology to really enhance those experiences. So we're going to go through a couple different things here. I'm going to talk about the first two, background transfers and how you can use that to minimize the install time for your app, so really enhance the installation experience. Then I'm going to talk about multitasking, some of the new APIs that John mentioned this morning, and how you can use those to really make your game feel alive and always be ready for when someone wants to play it. And then third, a colleague, another Paul, is going to come up and we're going to shift a little bit and talk about security and privacy and how you can take advantage of some of the new APIs that we have and best practices for building a secure game and respecting users' privacies. So let me just dive into background transfers.
And the experience, as I mentioned, the one that I want to focus on and explain how you can enhance really centers around this alert, right? The cellular download limit alert, which we, as we mentioned this morning, we raised from 50 megabytes to 100 megabytes, and that's great. That means a whole lot of games can now be installed by users even over a cellular connection.
And this is one of the most common questions that we get, is how do I get my app or my game under the cellular download limit? And that's a fair question, but it's really, it's not quite the right question. It's close, but not quite right. What I think is the right question is how do I minimize the install time? Because whether you're over or under the cellular limit, that's the experience you really want to enhance and improve is minimizing the installation time.
So to do that, I have a very simple checklist of just three items: taking inventory, using compression, and downloading things later. Now, the first two really are just best practices, and I'll go through those in more detail, but these are things that apply to all game developers and all app developers. And then the third one is where the new technology in iOS 7 comes in.
So going into taking inventory, what does that mean? Well, I want everybody to do an exercise here. So go in iTunes and download your app from the App Store on a desktop machine. And what you get is an IPA file, and iTunes can show that to you. You can use the context menu and have iTunes show that in the Finder. And that IPA file really is just a zip file. And if you've never actually opened the contents of an app, it's very easy to do. Just rename the file from.ipa to.zip and then uncompress it. And once you've uncompressed it, you'll inside there find your app bundle that you submitted to the App Store. And now go in the finder and say show package contents. And that will actually open it up in a file browser. And I want you just to review every file that's in that bundle. Because those are the files that are being installed by your customers.
And in particular, sort this by size. right? That gives you the biggest items at the top. And then just go through them. And I think a lot of you will find some surprising things. And I say that because this is one thing that we as evangelists at Apple, we do this a lot. When we get an app from you or when we talk to developers about apps, we do exactly this. And we find some really, really surprising things in there, right? We'll find readme files.
We'll find images that shouldn't be there. We'll find Photoshop images, right? An iOS device doesn't render a Photoshop document, so why should it be there? We find source files in there from shared libraries and things like that. So a lot of these end up in the bundle because they were dragged in in Xcode and inadvertently added as resources to your app. And in a lot of cases, that's not what you want. You may want it in your project, but not included in the app, the built version of your app. So that's what you're looking for, is just things that were in the App Store bundle that shouldn't be there. So if you find any, you go in your project, remove them as resources, and you'll save some space there. Now, another category of things that we find very frequently are obsolete resources. So most of the time, these are pieces of artwork from a design that now is obsolete, right? You've changed the design of your game over time, but somebody didn't remember to remove it from your project.
A really good example for app developers here would be as they move from iOS 6 to iOS 7, even in your games, if you updated the look of your game maybe to be in line with the iOS 7 visual design, make sure you go back when you drop support for iOS 6, go back and get rid of all those resources. don't keep them around because they're taking up space.
Now, another example, another case that we see are images or artwork that just take up more space than necessary. Here's an example of a button. We see this a lot with buttons and background images where the center pixels here really are just duplicated. It's this vertical row of pixels that's duplicated over and over. And so there's a lot of pixels in here that are extra and duplicate. So in Xcode 5, there's a new feature when you add images to an asset catalog that it's called the Xcode slicing. And you can come in here and say, well, these pixels are actually duplicate, and they can be stretched or tiled. And then at build time, what we can do is we can actually take that larger piece of artwork and just carve it up and compress it down and just take the bits that we need. So that's another way that you can save some space. So this first item, taking inventory, really just amounts to get rid of the garbage that might be laying around in your app bundle. So very easy to do. Now the second one, use compression. And you almost certainly are already doing this, but it doesn't hurt to point it out and for you to double check. And you want to focus on those things that take up the most space, right? The ones that's sorted to the top when you sorted by size. Commonly that's going to be video. So make sure you're using H.264 compression. You get great quality while saving space on disk. If your game has audio tracks-- most games do-- make sure you're using AAC compression, or at least MP3. And if you're using audio that's at 44.1 kilohertz, consider dropping that sample rate down to 22.05. To be honest, most players are never even going to notice the difference. If your game has a very, very crafted audio experience, that might be different. But for the general purpose game, a lot of them can benefit and save some space by doing this. And lastly, for big textures that you might have in OpenGL, consider using PVRTC and use images at four bits per pixel. So again, good space savings while maintaining very good quality.
So those are the first two items. Again, best practices that apply to every app and game developer. And now the third one, download things later. Let me explain what I mean by that. The idea here would be to identify things in your app bundle that you would normally submit to the app store, but that you might be able to separate out and not submit them to the app store, but download them separately after the app has been installed.
So it sounds fairly simple, but it's important to point out that this really may not be right for all apps. And that's fine if it isn't. If you can't provide a great user experience by separating pieces of your game out, then don't do that. Leave them all bundled together and focus on the first two items, and then you'll get some good space savings. And there's really no one right answer for how to do this. So you need to evaluate this for your game and your experience. But I think there's a couple categories where it's very common that you could. And I'll go through a few scenarios in a second.
The other thing to point out is this will almost certainly add complexity to your game. You have to probably represent somehow to the user what the state of these extra files are, whether they're downloaded or not. You have to handle cases where they're not downloaded and you need them. Maybe the disk filled up, so you have to deal with disk space issues. It also complicates your testing matrix. You just have more scenarios to verify that your game functions correctly in. So there's a lot of reasons why this might add more complexity than it's worth. but there's also a lot of benefit if you consider doing it. So let me go through a couple strategies that you might consider employing. The first is simply download these extra resources after your app has launched the first time. So after your game gets installed and someone taps on it to launch it, figure out what platform you're on. Am I on an iPhone or an iPad? Is it a 3 1⁄2-inch iPhone or a 4-inch iPhone? Is this an iPad that has Retina display or is it an iPad 2? And then kind of figure out which resources, which subset of your resources you would need, and go download just those. So that's one approach. Another one that I think may apply to more apps, and games especially, is to lazily load these extra resources as the need for them approaches. In a game, it's a perfect example. If you have a game that has a linear progression, you have 50 levels in your game. When somebody installs your app, they're probably going to start at level zero or level one, depending if you're zero-based or not. And they're going to need maybe the first few levels immediately, but they probably won't need levels 20 through 50 until later on. So consider separating those out and then download them when they're approaching those levels. You can do this kind of transparently in the background, actually. And that's the new technology that we have in iOS 7 that you could consider using. which is this new background transfer service. What this is, if you haven't seen it already, it's just a service to upload and download data, and it's uploaded or downloaded in the background. And when I say "background" here, I don't mean in, like, a background thread in your process. I actually mean it's done in an entirely different process. It's handled by a system daemon that's running in the background in iOS.
What that means is your game can actually be suspended or it can be terminated. If we're in a low memory situation, we might terminate your game. And the transfer will continue being done because it's being handled by a system service now. Now, this background transfer service is primarily intended for large pieces of data to download, things that are big enough that you might not be able to finish doing those in your process before the person using your game leaves the game, right? So it's things that are big enough that just take too much time. And when these transfers are done, your game will get relaunched in the background, and then you can process the results of it, either, you know, unpack the downloaded files, or if you were uploading something, just handle the success or error state there. Now, all of these are implemented using the new NSURLSession class in iOS 7. And let me just go through a quick code example just to give you an idea of how this works and a couple pieces that are involved. So first, in order to create a new session in which you download things, you have to create a configuration object. And there are a few different configuration objects in our APIs for a couple different purposes. I'm focusing on one here that you get using this background session configuration method.
Now, you get this configuration object back, and you can do things like set up custom HTTP headers, configure network timeouts, authentication handling, things like that. And you can actually centralize a lot of your networking setup code by using these configuration objects. Once you have a configuration object, then you're ready to get an NSURL session. And you ask for a session with this configuration. And like many of our APIs, you provide a delegate, and here a delegate queue as well. And that's where we're going to send messages like progress indication, or if there is an authentication challenge that you need to be involved in handling, we're going to invoke it on the delegate.
So now that you get a session object back, you're ready to begin adding tasks to it, right? Adding requests to be downloaded. And you do that simply by having a URL to a remote asset, you know, these separated out files that you took out of your App Store bundle, and you ask the session for a download task with that URL. And when you get that back, that's the object that represents the task happening in this background daemon. And by default, it's paused, So the transfer doesn't start immediately. And in order to start it, you just simply call resume on this task object, and that will start in the background then. Now, these tasks, these task objects are, they support all the common operations that you would expect of a network transfer. You can suspend them, you can resume them like we saw, you can cancel them, you can query for progress and things like that.
These are the objects that you might use to build a UI representation around them. Now, there's a new UI application delegate callback that will be used and has the methods called on the delegate object that you passed in. And then importantly, and I'll talk about this again in a second, there's a completion handler passed to your UI application delegate. And this is kind of a new emerging pattern that we have for a few different pieces of API.
In this delegate method, you'll commonly re-establish your connection to the session, the NSURL session. You'll get the tasks that are completed and then handle the results. Now, as you implement this delegate method, there's a few things, there's a few really important things you should be aware of. The first is, when this method is called, you only have a short amount of time to execute if you're in the background. And by short amount of time, I mean about 30 seconds, you know, seconds rather than minutes. You can inspect the amount of time you have available using the UI application background time remaining property.
That'll tell you how much time you have left to process. And that completion handler that I mentioned that was passed into the delegate, it's critical that you call it, and you call it as soon as possible. Because if you don't call that, indicating that you're done handling the results of the transfer, then iOS may terminate your app. And this is very similar to if your game doesn't launch, or suspend, or resume fast enough, the iOS may terminate the app because it's taking too long, and it may be stuck.
Now, it's also very important to be aware of data protection. As you adopt this new API, this may be the first time that your game is actually in the background and running. And in some scenarios, when you're in the background, if the device is locked and there's a passcode on the device, then some files on disk and items in the keychain may not be available. And this is because of how data protection works. So if you're not familiar with data protection, This is a really important thing to read up on. And actually, in the security part of this talk, we're going to go into more details on data protection.
Now, once these transfers are done, NSURL session is only going to hold onto this data on disk temporarily, just up until the point the delegate callback is finished. So if you need to keep this data for an extended period of time, which in my example of downloading these extra assets for your game, you probably do, you need to take responsibility and move that into your app sandbox and store it somewhere. And as you're deciding where to store things, It's important that you read and understand the iOS data storage guidelines. The app review team will be enforcing these guidelines, which spell out what types of files should go where on disk, what types of things should go in the app support directory, in the documents directory, in temporary. And it also explains which of those files will by default be backed up, especially to a user's iCloud backup. And we're concerned about the usage of space in users' iCloud backups, And that's why it's important to be aware of what's getting backed up. And this is one of the common causes for rejection by the app review team, is having files in the wrong place, and they get included in iCloud backups.
So to exclude things from a user's backup, it's very simple. There's an API on NSURL, so wherever you copied these files to, if you need to exclude them, just call this setResourceValue for key, and you set this one particular key, NSURL is excluded from backup key. And that'll keep it out of the user's iCloud backup, and it'll keep the app review team happy. So those are the three items for minimizing install time. And these, especially the first two, may seem really basic and really obvious, but we see this so frequently as we review apps with developers that it's really, it's worth pointing out here. And it's worth, you know, you including in, especially your pre-submission checklist, as you go through your checklist of items before you submit something to the app store. Go through these items and just make sure that you're minimizing the size of your app bundle, because that'll give a great install experience.
So using background transfer, you can make sure you clean up and compress things, and then consider splitting extra files out. NSURLSession is really the future of foundation networking. So if you're using the networking at the foundation framework layer, you want to be moving now to NSURL session. Eventually, NSURL connection will get deprecated in favor of NSURL session.
So start that transition now. Okay. And be careful with the iOS data storage guidelines. Just make sure you're putting the right things in the right place and keeping things out of the user's backup that shouldn't be there. So that's background transfers. So let me move on to multitasking.
As John talked about this morning, the multitasking APIs and the UI in iOS 7 have evolved quite a bit. Now this is what users see in the app switcher. They see a great snapshot of your app, your game. They can see the state of the app, what's happening in there. And the experience I want to focus on that I want all of you to consider how you can improve this is by keeping that app snapshot up to date, right, that will really present to the user that your game is alive. And a lot of games have state that changes over time.
And it's really important to reflect that state here so that as users are swiping through these apps, they can really quickly see, oh, look, something's happened in my game, so let me go see it. You know, there's three examples that I want to call out, three kind of styles of games where I think this can really help. Here's Badland. Incredibly great game. But you look at this snapshot, and it's actually not really right, because this is actually showing as if I was in the middle of playing the game, right? Which is what the state was when I left it. But when I go back into the app, that's not the state that I'm in.
When I go back into Badland, the state I'm in is actually paused. So the game got paused, but that wasn't reflected in the snapshot. So that's the type of thing that I want you to think about. How can you make the snapshots more accurate and more up to date?
Now, another style of game, here's Clash of Clans, right? So a resource management game where there are things in these games that actually take real-world time, right? I'm training some new troops here. It's a little hard to see in the screenshot, but I've got about an hour of time left before those troops are trained and ready to go do battle for me. Now, over time, what I'd love to see is kind of that time being updated periodically as I use my device. So that's another example where updating that snapshot can really improve the experience. You know, or Letterpress, another great game.
Here, maybe what I want to see is as push notifications come in, indicating that somebody's turn has been taken, you know, maybe I want to see that reflected here. Now the little triangle has moved back over to me. So those are the types of things that you can do with these new multitasking APIs. So let me go through the typical sequence of how these app snapshots come into existence and then what's new in iOS 7.
So the typical scenario is your game gets launched, and you'll update your state. You'll contact your server. You'll get the latest game state. You'll figure out, are the troops trained yet or not? And then you'll update the UI and show that to the user. And that's kind of that ever-present, like you launch a game or launch an app, and you have to wait for the spinner to finish spinning before you're ready to use the game. That's what we want to get rid of. Make your games always ready. So you update your UI. Player plays a game. They're having a great time. My troops are ready. I go to battle. Then I hit the Home button. I leave. And now the app suspends, and iOS will take the snapshot at that point.
Now, in this flow, this one is really user-driven. And in this case, at the end where the snapshot is taken, that's where you might want to reflect the state of the game being paused, just before the snapshot gets taken. Now, in iOS 7, we've got a couple new entry points into this flow that are not driven by user activity. They're actually driven by iOS. And these are two new background modes called Remote Notification and Background Fetch.
These are new background modes, as I mentioned. You can configure them in Xcode's capabilities pane. And if you look at the list of background modes, we now have two new ones down at the bottom. And the interesting thing about these background modes is unlike the other ones, which are very narrowly scoped, they have a very specific purpose, like background audio playing or location updates or if you're a VoIP app, those are specific background modes that we only let certain apps use. These two new ones are general purpose, and they're usable by everybody. And actually, we want them to be used by everybody, because we think it can improve these experiences.
Now, because they're initiated and really controlled by iOS, we can do so in a power smart way. Another thing that John talked about this morning. We can ensure that we're not going to be draining the battery while letting you have this background time to run. So let me go through both of these and explain a little bit more what they are. The first one, remote notifications. What this means is when a push notification is delivered to an iOS device for your app, with the new remote notification background mode, your app will get that even if it's in the background. And this is a big departure from iOS 6, where in iOS 6, you would only get that push notification if you happen to be the frontmost app, right? if you happen to be running and your app was front-most when the push came in.
Or second, when the user tapped on the action button to launch your app. But at that point, you know, it's kind of you're already behind the game because the user said, "Yes, I want to act on this." But now you start the process of doing your update and whatnot, and that's where the spinner comes in. So with remote notifications, when the alert goes up on screen or when the sound is played, your app is launched simultaneous with that. And you can start updating immediately. So that gives you the chance to be up to date when the user taps on the Action button and gets into your app. So you're already ready.
The way you do this is in your push payload, which might look like this if you just have an alert, you add this content available key. And that's the indication that we should deliver the push to your app, even if you're in the background. And so that's great. That's a really nice improvement over iOS 6, but it's not what I think is really cool in iOS 7. What's really great is something that you've all asked for for quite a few years now, and that's the ability to send pushes that are silent.
And now in iOS 7, if you have a push notification and you omit the alert or sound or badge key and you only include the content available, you can have custom stuff in there as well, but if it only has the content available, then that push notification will be delivered to your app even if it's not running and there's no user visible indication that that push came in. So it's kind of a private channel of communication from your server to your app. And that is something that a lot of you have asked for. So we're really excited to bring this in iOS 7. So that's remote notifications.
And the second new background mode is called Background Fetch. And what this is designed to do is give you additional opportunities to execute in the background, primarily for the intention of fetching new content from your servers or social feeds or wherever it might be coming from. And in both of these cases, in both of these background modes, This is what gives you the opportunity to do some kind of fetch or do some kind of work and then update your UI and update the snapshot.
And as I mentioned for background fetch, this is initiated by iOS. And it's based on two things, either previous usage of your game, where in the letterpress example, I play that usually in the morning and then in the evening. And iOS notices that pattern. And it will begin launching letterpress a little bit before I usually go into the game, so that it has a chance to get up to date before I launch it. The second time is just when it's a good opportunity, when a device is plugged in, when we know we're on a network, when the screen is turned on, the user is actually interacting with the app. We typically have a lot of horsepower that's not really being used. So we can take some of that time and that processing power and let apps do stuff in the background. So the way of thinking about this is just for your game, be prepared to be launched in the background if you add this new background mode. And that'll give you some extra time to run. Now, if we go back to this flow here, you can see there's new entry points into this flow, and very similar to the background transfer delegate method, each of these new background modes has a UI application delegate method, and it has a completion handler with it. And when you're done doing your update, you call the completion handler, and that's our indication that we can now suspend you, and now we'll take a new snapshot. And that's how you can keep that snapshot up to date.
And when you're updating your content, a couple similar important things to consider is call that completion handler as soon as possible. You have this short amount of time, but it should be plenty of time to do a simple update. But you do want to keep your fetches small. You know, maybe fetch just the metadata, the new game scores, or whose move it is, and maybe just the minimal amount of information about that last move. If you do have large pieces of data that you now know you want to download, well, that's a great use for the background transfer service that I just talked about. So you can use these new technologies in conjunction with each other.
And for a lot of games, you use OpenGL. And up to this point, we've told you don't use OpenGL in the background. In fact, your app will crash if you do that. So now, in the context of these new UI application delegate callbacks, it is OK to use OpenGL for the purposes of updating your UI in order to update that snapshot. If you can render just a single frame, that's great. So just do that, do the minimal amount of work you need, and be careful about loading in lots of resources if they had been unloaded. So you want to be minimal usage of memory and time, but it is OK to use OpenGL. That's the important point.
And again, be aware of data protection. One of the common things that we've already seen by developers is when you need to go do a fetch from your server, you probably need to sign in somehow and have credentials. And when data protection is enforced, if the device is locked and you're being invoked to do this background fetch in the background, you may not get access to those credentials. So just handle that case correctly. We've seen it trip a few developers up already. And we'll talk again more about data protection in a moment. So that's multitasking and how you can use the new APIs to really improve the experience of the app snapshots. So keep them up to date. Keep your app state always ready. Remote notifications let you get these push notifications even when you're in the background. And background fetch are just new opportunities to fetch and update state while you're in the background. And last time for me to say this, be aware of data protection and when the device is locked. Now for both of these first two items that I've covered, we had a couple WWDC sessions this past summer. What's new with multitasking? Obviously went into the multitasking APIs, and I've only scratched the surface on here just to give you an idea. What's new in foundation networking? Talked about NSURL session, and not only the background transfer service, but the other pieces of functionality that you can use for NSURL session. So definitely check those sessions out.
So that's background transferring multitasking. Now for the third item, I'll hand it over to my colleague Paul Danbold to cover security and privacy. PAUL DANBOLD: Let's start by just making sure we all agree. Security and privacy are important. They're in the news every day. But thanks to a lot of hard work on our side and your side, very rarely is iOS mentioned or your apps or games. So we're in a good spot, but we want to maintain that reputation and get even better.
Here's what we're going to talk about, just to let you know in advance. On the security side, we'll talk about data protection, and Paul was talking about that a little bit earlier on. Protecting the data that you send on the wire, so to speak. A little bit about defensive coding. And then when we get to privacy, we'll be talking about identifiers, about data isolation, which are the mechanisms that arbitrate access to personal data and device features. and the care that needs to be taken with logging runtime events and glitches in ways that protect user privacy.
So on the security side, I'm going to start by just with a couple of high-level comments here. You know, do these kids look like security experts? And quite frankly, today, maybe they are. But most of the people who play your games probably aren't. You know, it's fine to ask for a login name and password. But generally, it's futile and just plain annoying to present any kind of security alerts to the people playing your games. So you've got to do the best you can to protect the personal data that your apps have access to without pestering the user. In other words, good security is mostly invisible.
And another thing to remember is that there's no such thing as unbeatable security. You know, there will always be bad guys looking for vulnerabilities in the OS and possibly in your games. But if you do the things that we're going to be talking about in the next few minutes, you're not going to be a soft target. and attackers being just human beings like all of us are likely to gravitate towards easier, more vulnerable platforms and softer, less secure apps.
So protecting data on the device. So this is a data protection topic. And this isn't just about game scores. We see people use apps and games in very creative and unexpected ways. So if there's the slightest possibility, an NSString or NSData or some other object contains something that would be bad news if it got lost or stolen, you should protect it. You can't be too safe.
And one of the things I do when I'm looking for possible security flaws in any app or game is, you know, get it installed on my iPad or my iPhone, hook the device up to my Mac, and then I've got some device management and forensic apps that I can use. And, you know, here you can see with a screenshot from one app, it's very easy for me to pull all the files out of an app's container back to my Mac, take a look inside the files, maybe run the contents through a decoder if the contents aren't immediately obvious, and possibly find something that's interesting or lucrative. And I don't need to be a programmer to do this. Anybody can get these tools. And so basically that's why you need data protection. In a nutshell, all it is, and I'm not going to go into any details, it's you telling us the OS when you want access to your keychain items or any files you have, and when you want us to safely encrypt them.
And it's such a lightweight task to do. Take a line of code like this and specify a data protection class. So it's extremely easy. Here I'll just list the data protection classes first for the key chain, then for the file manager and core data, NSData, and we actually have some for SQLite as well. And it boils down to this. Use the strongest protection class that's accessible when unlocked for the key chain and protection complete for files. Use that -- use the strongest protection class wherever you can. But if you need access to, say, a keychain item or a file when the device is locked, you can also do that with a level of security, and that's where the intermediate protection classes come in, and that's what we'll talk about in a couple of slides. By the way, dot, dot, dot means there's even a less secure protection class, but just don't use it. There's no good reason.
So when the device is locked, a lot of you have games that are backed by a server. And the scenario is you keep the credentials to log into your server in the key chain. You support the new multitasking modes in iOS 7. And you need to access or you want to access your server while the device is locked.
So how do you do that? Well, you can't use the strongest key chain protection class, accessible when unlocked. But you can use the intermediate protection class, which is accessible after first unlock. Slightly less secure because the keys are kept in memory until the device is actually turned off instead of until the user locks the device. But you can take some measures to mitigate the risks. You can treat items like this as read-only. You can purge them after some period of time. And you can go even further here. You can do, let's say in the case of passwords, You can create what we call a derived key from the user's password. So the derived key gets the intermediate protection class. The user's real password gets the stronger protection class. Your server needs to recognize the derived key, but if that derived key fell into the wrong hands, it's pretty much impossible to get back to the user's real password from the derived key. So the user's safe, and you've got a mechanism to access your server while the device is locked. And PBKDF2 stands for password-based key derivation function. It's a widely used technique. We've got all the APIs to do this in the common crypto library.
And on the same theme for files, also, if you want to access files while the device is locked, you can do that. And a good example here is following on from what Paul was talking about, the new NSURL session background transfer service. So what you do here is use one of the intermediate protection classes for a file that gets downloaded in the background. And when your app is or when your game is active again, check the data that's been downloaded.
Check it's okay. And if it's okay, you can upgrade the protection class on that new file or maybe merge the data into another protected file. Thank you. I'm going to mention a few other things that are new in iOS 7. One is that, you know, we all like the fact that, you know, you can synchronize your calendars and notes and contacts, et cetera, via iCloud, and we've been doing that for a while. But now you can do that with keychain items. So this isn't for every kind of keychain item. You want to think through the implications. but if you set this new KSEC at a synchronizable attribute on a keychain item, obviously with a value true, it will be automatically synced. So if I've got your game on my iPhone or my iPad, something that you store in the keychain will be synced across those devices. You need to think through the implications of, you know, adding, updating, deleting, logins, and things like that, but it's something you may want to take advantage of. I should mention it's not for all kinds of keychain items. It doesn't apply to certificates and keys. It's for passwords, but when we say passwords, that category can cover a lot of things, an account name, number, or something like that. And if you have multiple apps and you share your keychain items using the Keychain Access Group entitlement, those items can be synchronized. Just make sure all the apps use the same KESAC ATTA access group name.
Okay, so that's data protection, and the bottom line here is it's a huge bang for the buck for almost no code on your part. But again, what we're stressing today is make sure you understand the right data protection class to use for keychain items or files that you may need to access when the device is locked. And I'll say one more thing, which is that even if you do everything right on the device, which hopefully you do, you really should think about everywhere that that personal data can be. So it's beyond the scope of this talk, but it may be not only on your users' devices, but on your server, et cetera. So a lot to think about there.
Now, secure transport, you know, it's near the bottom of the iOS network stack. You can, but you probably don't code directly to the secure transport APIs. You're more likely to use the higher-level frameworks. But it's down in secure transport where the network security protocols are to be found.
Now, I really can't do justice to network security in a few slides, but I'm just going to focus on a couple of things that I want you to take away from this talk. One is kind of like the example I gave for how easy it is to get an app's container. It's really easy to see what any app or game is doing on the network.
You know, here's a screenshot from Charles' proxy. I use this basically to turn my Mac into a man-in-the-middle proxy for HTTP and HTTPS traffic, and I can see everything that an app is sending, you know, typically back and forth between its server. And fortunately here, it's all gobbledygook on screen, which is great, because this app that I was testing with is making sure that all its network traffic is safely encrypted. And the point is, you should be using tools like this, packet sniffers and protocol analyzers, to make sure your games are networking securely, because attackers can use exactly the same tools to see if they can find out what you're doing on the wire.
You know, there are two things about secure networking, two essential things. One is what we call on-the-wire confidentiality. That's basically making sure everything you send and receive is indecipherable to the passive attacker, which is the packet sniffer. And the other thing you need to do is authentication. And this is making sure that the server you're talking to truly is the server you want to talk to. In other words, you don't want to be vulnerable to a man-in-the-middle attack. You want to authenticate the server. Sometimes the authenticator, sorry, sometimes the server wants to authenticate the device. But I'm not going to get into all of this. You need both things that I just talked about, confidentiality and authentication. And, you know, there's a lot of ways of getting this. You know, the obvious one is TLS. You know, that's just the S in HTTPS. And it's very simple to make sure you're using a secure networking protocol by using HTTPS. But it's not your only option. And it's a fairly heavyweight protocol.
You may want to use a lightweight streaming protocol for your games. I just want to make the point you should make sure that your network traffic is safe from any kind of attacker. And most importantly, when you've got your code working, use the tools that I just mentioned to make sure that all your network traffic is secure. In the real world, a lot of people use the same credentials for multiple services. So even though you may think that... If somebody intercepts your network traffic, you know, not much damage can be done. But unfortunately, you know, people do tend to use the same credentials for multiple web services. So if somebody can steal credentials from the network traffic your app's engaging, then they can potentially use those credentials to try to, you know, gain real money from, you know, other web services that the same user may have. So think about that. Now, secure coding, you know, most times when people talk about secure coding, it's the well-known topics of buffer overflows and unsafe string formatting. I'm just going to give you a few things that I want to get you to do regularly because they're very lightweight and they're worthwhile. Thank you. Use Clang. That would be my main recommendation. So easy to do, the static analyzer. It'll find exploitable flaws and bugs in your code. Just make it part of your daily development and testing practice.
If you have any text that could possibly contain any sensitive information, market a secure text. And you can do it programmatically, as you can see here, or in Interface Builder. Secure text, we don't cache it. We disable auto correction. And of course, if you're ever asking your users to provide a name and password or just a password, use the secure text input or the login and password input alert view style methods just to mask what's shown on screen.
If you've got any object that might contain sensitive information, don't hold on to it after you've used it. Just purge it. It's really very simple to do. Well, actually, sometimes not so simple. Maybe you have to drop down to core foundation or lower. But it's worth zapping anything that could possibly contain sensitive information. And I could have added a lot of other examples, you know, keeping sensitive information out of NS user defaults.
And the list goes on. And the point is that most of these things are obvious. Hopefully most of these things you're already doing. But we have seen a few cases where a developer maybe in too much of a hurry to get their apps or their games published has overlooked these straightforward measures and found themselves in the headlines.
If you're worried about your games being run on compromised devices, jailbreak detection, we don't usually talk about it, but I'll just say a couple of things. First of all, it can be tricky. You want to make sure that if you go down this road, you don't jeopardize the stability of your app or interfere with day-to-day development or testing, or even worse, impacting users running your games on legitimate devices.
And, you know, if you look at this code, a little jailbreak detection snippet, this will work as long as the attacker hasn't patched F open. And you can scour the web and you can find scores of examples of so-called jailbreak detection code. And they usually try to do things that are blocked by sandboxing. Now, I'm not saying don't do this. You can frustrate an attacker.
But we also have to recognize that an attacker with enough skill and patience will overcome these kind of defensive measures. And that's why basically we don't have an API to tell you you're running on a compromised device because obviously that would be the first API that an attacker would hijack.
So before we move on to talk about privacy, just want to say this. Do a periodic audit of your games. Make sure you're using data protection where it makes sense for you. Make sure all your networking is secure. Make sure you're adopting some fairly basic and very lightweight defensive coding practices.
Now, on the privacy front, you've seen us in successive iOS releases give users more and more control over what apps can do with their personal data. And you've seen us deprecate and remove mechanisms that allow apps to track devices and possibly users. On your side, you really need to have a reputation as a developer who takes privacy seriously, and you need to make it easy for users to find out what your games do with any personal data they have access to.
This section on identifiers is going to be short because it's old news, hopefully old news for all of you. No more long-lived identifiers. It's all about what we call purpose-scoped identifiers. And we rolled these identifiers out over a year ago. So, you know, we deprecated the unique identifier API, and we said, "Everybody, you've got to use the app ID, the vendor ID, or the advertising IDs as they were designed," and I think it's fair to say pretty much everybody's using them now properly. Just remember, these identifiers don't last forever. They are backed up. In most cases, the vendor ID replaces the old UD ID. And just a word of caution, the advertising ID, if you use it, just remember, users can reset it at any time.
We also cranked up privacy protection in iOS 7 in a few other ways. We couldn't deprecate or remove syscontrol and iOctl. They're used for other purposes. But you don't want to be using the MAC address as a device identifier any more than maybe you were using the old UDID. And using the MAC address for that purpose was always a bad idea, because it's so easy to spoof a device's MAC address on the network and get access to things that you didn't pay for.
In case it affects you, push tokens. They're now scoped to the app. So it's never a good idea to cache them. You always have to use the value returned by did register for remote notifications with device token. And one other thing to mention to round up this list, named pasteboards, they're now scoped to your team ID. So you can share custom pasteboard content between your games, but no further.
So we've been beating the drum on this topic, identifiers, for quite some time now, at least a year. I think everybody's got used to the fact that the old UDID's gone. But if you've still got questions, more than happy to hear from you. Now consent and transparency, this is all about the consent alerts.
We have been giving users more and more control over different classes of data and device features. And... You need to understand how this works. And there are really three things you need to do. You do need to make sure that you can handle the case where the user says, don't allow. You need to help the user understand why your game wants access to certain kind of data or device features. So that's where what we call purpose strings come into play. And very important, test. Test all the scenarios to make sure your games behave correctly, as privacy settings can change at any time.
You know, when you ask, let's say, call location to start updating your location, that's what triggers the consent alert. And getting the users okay or don't allow happens outside the address space of your app. You find out about the permission asynchronously, either through a delegate or a block method. And here are all the things that are covered by the consent alerts. I'll just highlight a couple of things that are new in iOS 7. One for the microphone. If you ask for an audio recording session, the user will get a consent alert. And if the user decides to say no, you will get silence. That is, you'll get an audio stream of all zeros. And hopefully a lot of you are thinking about or already adopting Core Motion. So that's another example of a device feature that's covered by the consent alert. And there are two things you need to do. One, obviously, is try to keep your game as interesting and engaging as possible, even when the user says don't allow.
And the other thing is nobody wants on launch to see a bunch of consent alerts. So delay until you really need access to that kind of personal data or device feature. And then the consent alert will actually make sense. It will be in context for the user. So they're more likely to say yes.
and helping them decide to say, "Yes, this is where the purpose strings come into play." In your app's info.plist, you can go in, find all these, what we call the usage description strings for all these classes here, put in the sentence that is going to help your users make a good decision about granting your game access, and of course provide localizations.
And on the testing front, test all the scenarios. Make sure that your game behaves robustly, whether the user says yes, don't allow, when the user changes her or his decision about granting access at a later time, and when restrictions are in place on the device. And note, the consent alert will only come up once per category for the app. So you're going to have to toggle privacy settings between test run and the next. But also, it's important to understand you've got to do this testing on the device itself. At this time, you can't use a simulator for this kind of testing.
So just one more topic to go, and that's data collection. So this is just a short version of what we went into detail in the last two WWDC privacy sessions. It's totally understandable that by collecting data, you can find out what aspects of your games are most popular, and where you need to tighten up code in the case of logging crashes and other events of interest. So you can log data, of course, but you want to think about it like this. If the data you collected fell into the wrong hands, could you explain to your users why you were collecting that information in ways that they would say, okay, I understand and I agree to that? So whether you're collecting data on the device or storing stats on your servers, do everything you can to eliminate any kind of sensitive information or personal information.
And somewhat related to that, it's always a good idea to have a privacy policy statement. Write that up, provide a link to it in iTunes Connect, and then your URL is accessible from all the App Store clients. And one more thing, I'm sure you're all familiar with App Store review guidelines, and there's a privacy section in there. Fairly recently, we added a clause that you should pay attention to if your games are used by children.
So we've covered a few things about privacy and security before that, and hopefully as we've talked through these various topics, you've said, yes, I do all these things. And if you do, I'm happy. Congratulations and thank you. And last... Thank you. Email addresses for the two Pauls. And just a plug for the developer forums, because that's where a lot of you, I'm sure, hang out. And you'll see all these topics we just discussed usually actively debated pretty much every day. So thanks a lot. Thank you.