Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2012-303
$eventId
ID of event: wwdc2012
$eventContentId
ID of session without event part: 303
$eventShortId
Shortened ID of event: wwdc12
$year
Year of session: 2012
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2012] [Session 303] Staying on ...

WWDC12 • Session 303

Staying on Track with Location Services

App Services • iOS, OS X • 50:55

Location Services provides a variety of services to know where you are, where you're headed, and when you've arrived. Come hear details about improvements to the CoreLocation framework in iOS and exciting new additions in OS X. Learn tips to let you get the most out of the framework in a power-efficient and user friendly way.

Speakers: Jay Bruins, Mike Dal Santo

Unlisted on Apple Developer site

Downloads from Apple

HD Video (319.2 MB)

Transcript

This transcript was generated using Whisper, it may have transcription errors.

Good afternoon. My name is Jay Bruins. I'm a software engineer with Apple. I work on the Core Location Framework. And I'm here to talk to you guys today about how to stay on track with location services. So in this hour, what we're going to cover is-- we'll start with a quick overview so that those of you who maybe are new to the framework can maybe have a chance to quickly catch up and a quick refresher for everyone else.

Then we'd like to move in to talk about some improvements that we've made in this last year, some things that we're really excited about, and then a couple of changes for you guys, some things you can adopt to make your programs better. And then lastly, I wanted to go over a handful of things that you can do to basically fine tune your application to really give it your users the best experience. So with that, I would like to start with a quick refresher. So you might be asking yourself why you're sitting here. Why are you, I guess, interested in location at all? And to us, the answer is because location provides context to your If you are sitting at a desktop computer, you probably always know where you are, you are in your office. But iOS is an inherently mobile platform. In many ways, your phone is your viewpoint on the world. And so there's a lot of cool things that you can do if you are interacting with your users in a way that they are expecting. So, for example, users drive everywhere. But, I mean, if you could enhance their behaviors by giving them something that really makes it clear how to get there faster, that's really useful to them.

Similarly, if you have an application that provides them with information and you know where they are, you can give it a more intuitive experience. And then lastly, there's plenty of stuff we haven't even thought of yet. So finding your friends or checking into a restaurant, these are things that weren't really even thought of until the last couple of years. So there's just a lot of cool things that you can do with location. So what do we mean by location?

Well, we bake a couple of technologies into Core Location to make it easy for you guys to use. So we take care of all the hard work, but to give you a quick overview of what's kind of going on under the hood, we start with a cellular position. And so basically this is your lowest level of accuracy, but it's the least amount of power. Basically it's hey, look, the user's camped on this cell tower. We have a relatively decent idea of where they are. Then we also have Wi-Fi positioning. Wi-Fi doesn't have as much power a cell, you're much closer to it. So the result is that, you know, we've got a slightly finer grain of accuracy. And then lastly, what a lot of users think of when they think of location, they think of GPS or we're going to say global navigation satellite systems. And I'm making the distinction because we actually support both NavStar, which is what you normally think of as GPS, and the Russian constellation GLONASS. So with this, basically you don't ever have have to worry about all of these. Basically, you know, we handle it. You just tell us what level of accuracy you want and we figure out what technology you need and we can deal with the user's battery level for you. So with that, a quick recap of what the API actually looks like. So any location app that you're going to have is basically going to have a couple of key parts.

The first thing is you're going to boot up a location controller that's going to manage location for your application. And it's going to have a handful of methods. So for starters, you're going to have a setup method that's just going to instantiate a location manager and you're going to go ahead and configure it. So create one, set yourself as its delegate so you get the callbacks from us, and then you're going to tell us what level of accuracy you want. So if you're doing a turn-by-turn based application, you'd probably want to register for best for navigation. If that's not what you're doing, maybe you want something that's much lower accuracy so that you also save the user's power.

And then all you have to do, user decides, hey, I'm ready to use location. And you go ahead and start updating locations. And then with that, we go ahead and give you a callback that says your user moved here. And then you can take appropriate actions such as updating your view. If you're a fitness app, maybe you store it to some data model. And basically that's kind of the quick overview of how location works. So with that, I'd like to move on to what we've done in the last year to really kind of improve location. So there's three main things that we've done. The first is we've improved accuracy significantly. The next thing we've done is we've also improved the availability of location services in general. And then lastly, we've also helped to lower power consumption of location on your users' devices. So their battery can last longer than ever when using your apps.

So let's look at a couple of these things. What do I mean by improved accuracy? So let's consider our lovely city of San Francisco here. San Francisco, if you're in kind of the eastern side in the downtown area, it looks a lot like this, like your major metropolitan area. You get these big, tall skyscrapers that block the GPS satellite signal. So with that, it's called an urban canyon, and it's a really, really difficult environment for GPSs to work in. And so we actually take devices, And we drive around San Francisco a lot. And we particularly pick on this one block that's got those nice buildings that you saw right there. And the result is that we drive around and we look at our GPS performance. And we get something that looks something like this. Now, this looks a little bit sloppy, but quite frankly, most vendors would love to have a location solution that looks as good as this does with just GPS. But we're Apple, and we also have iPhones that have Wi-Fi radios and cellular radios and a whole bunch of other technologies baked into the phone. So we don't just stop at GPS. If your user has Wi-Fi, now in iOS 6, they'll get something that's an experience that's a bit more like this. But that's not all. As you know, Maps just launched with some beautiful new vector data, which actually is useful for location as well. So now your experience if you're driving in downtown San Francisco will be something more like this.

There's two main parts. Let's start with what I mean by Wi-Fi-aided location. So like I suggested, basically we take the horizontal outliers, say you're driving through San Francisco and you see these peaks in uncertainty where we really don't know what's going on. You've got signals reflecting through windows, you've got buildings blocking others. So if we add in Wi-Fi information, we can actually reduce the location accuracy so it looks something more like this. So basically we just take those really, really bad peaks and we drop back down into the floor. And it looks a lot -- basically it's an incremental improvement that really helps as a good stepping point for other technologies. So that brings us to map-aided location. So what map-aided location does is we basically take the raw GPS and course -- the location and course information from GPS and Wi-Fi. And then we look at the -- consider the question of is your user driving? Now, if your user is driving, A, they're much more likely to be on a road because most people courses.

And the other reason why it's important is because there's a lot more sensor information from driving. So your course is much more reliable. So with that, if we have vector data available to us or we decide to download it, the result is that we can consider all of these things and decide if bringing you closer to a road is more accurate for your user. And so we will improve location if it's possible for us to do so. So the reason we do this is for, say, improving turns. A different part of a drive test, this is the Transamerica pyramid.

We have data that looks something like this. Now, it's clear that the user probably didn't go through that plaza. And in fact, if we add Wi-Fi in, you start looking more like this. But again, if map aiding is available because you're driving, the result is this. So this helps a lot if you're trying to understand where your user actually is and you're trying to provide directions, or just generally keep track of any sort of location accuracy.

But like I mentioned, we only do it if it's possible. So one of the key tenets of when we turn this on is the question of can we do this without any harm? And so with that, we actually added another spot on our drive test, and we stopped for donuts. And I don't mean the manly donut shop. I actually mean we go into the parking lot and we do donuts.

So this is not an urban environment. As you can see, we actually are doing very, very well with just GPS and Wi-Fi. But we can still do it-- so when we turn on map aiding, we actually don't do much. You're a little bit closer to the roads, but when you get to the parking lot, your user's track is left alone.

And so we don't really have any road data there, and so we leave the user right as they're driving, having fun. So this is really cool that we can selectively apply map aiding when it's really beneficial to your users and not when it's going to change their data to ways that don't make sense for you.

So with that, I'd like to move into the topic of availability. And so there's two forms of availability I'd like to talk about. The first is we've brought some new APIs over to OS X. Specifically, we've brought over the ability to do geocoding. So now you can look up locations on OS X. And we also can use the region monitoring API. So to give you a quick recap of what these are, I pulled some slides from last year specifically to go over this. So reverse geocoding, basically you start with a lat long, some human readable number that doesn't necessarily make much sense to a user. And then we can convert it for you into an address. And actually it's not usually just an address. Usually we'll give you the name of the restaurant, a whole bunch of other cool things that are associated with that parcel. Similarly, if you were trying to navigate -- if you're trying to drop a pin on a map, we have forward geocoding. So with forward geocoding, you start with the address that the user gives you, either there is a dictionary or a string, and you convert that into Latin along. And so with the latitude and longitude, it's plottable on a map. You can figure out some distance calculations as the crow flies.

You can do whatever you want with that. So that's useful to your users. But with region monitoring, what you can actually do is you can take one of those latitudes and longitudes. You can create a location coordinate. And then you can instantiate a circle around it. You can basically just create a little region, say say, 100 meters. And then you can give it a name, say, Apple Inc. And then with that, you can basically tab your controller object, send it to the framework, and tell us, hey, we want to start monitoring for this region. And so the result is that your application can go into the background, not be running, can even be stopped completely. And if we find that the user enters that region or leaves that region, then you get a notification from us or sometimes a launch event to say, hey, look, your user is now at Apple or your user left Apple or whatever the user is doing. So this is great because it saves your user's power and it allows you to make sure that you're running at the time that your user needs you to run.

So if you're Passbook and you want to be able to display a movie ticket when you show up at the theater, well, if we know where the theater is that you're gonna see the movie, then you hit a fence, all of a sudden, the ticket shows up on your phone, and everything works great.

But by bringing these to OS X, we've actually enabled the ability to bring the reminders application to OS X. And so reminders now works just great on your desktop, you know, homework, notifications, they're great. As long as your computer stays running, so if it's slept and not actually shut down, it'll work just fine. A quick example of how geocoding and region monitoring kind of play together. So if you were going to say install a reminder for something that was interesting to the user, like where I work, And then what you do is you take an address, you create a geocoder object, and then you call a geocode, make a geocode request, which you pass a block, we'll go hit a server, asynchronously call you back, and then you can decide that you want to start monitoring for that region. And so you just pick the best place mark of your choice, start monitoring for it, and again, we give you this callback saying location manager did enter region, and we have a similar one for exit, and you can just, since this is OS X, you can display an NS alert to tell Hey, look, you're back. Great.

So with that, let's talk about some other forms of availability, specifically Wi-Fi availability. So as many of you already know, if you're sitting somewhere and you've got a location and you do a Wi-Fi scan, what we do is we take those results and we send them up to the server and the server says, hey, look, we know about all these Wi-Fi hotspots in this whole area. Here you go.

And so now your device without any more talking to the server can wander around for some finite distance and figure out where the user is. But the problem is as you're driving around San Francisco and hanging out taking photos of people, you take one picture here, you take one picture there, you're not necessarily in the same spot. We don't hit the cache on the device. So the result is that we go to the network and we download yet another piece of information and you get a new little area. So now you can move around inside of this, but if you move somewhere further, then we have to go talk to the network again. So with iOS 6, we decided can we maybe do something better here? Can we maybe compress the data? And so what we did is we actually took all the Wi-Fi's and we mapped them into these tiles. So now in the same size as one of those data downloads that you saw on the screen before, you saw six of them, you get one of these instead. Same amount of data. That's five kilometers by five kilometers.

And the cool part is, if you're on Wi-Fi, we don't just download one tile. We'll actually download a whole bunch of tiles in that area so that your user can travel even further around the city. So if you pay for data at a coffee shop and then you use it, you can keep going. We have 10 times the access points in one piece of data. And actually, because we're smarter about the way that we choose the access points that we put into the tile, we actually get 60 times the coverage area. So it's just being a little bit smarter about it overall, and you would get this better performance. So with that, the advantages of Wi-Fi tiles are a handful of things. First off, it's basically instantaneous location. If you have -- if we know about the Wi-Fi's that are near you and we see one, we know where you are. Done. Fast. So passbook and weather, everything works instantly. Another cool thing is that we sell devices that don't have cellular radios, which means that if we can't download data, we can't know where you are. So now that we've got Wi-Fi tiles, we can bring things like region monitoring over to the device. Or you you could even, say, tag photos with information. So an iPod Touch, which doesn't have a GPS in it, can now take a picture and know where you are, and you can say, "Hey, look, this was at this place."

But it's not just Wi-Fi-only devices that benefit. Users travel abroad, and they don't like paying for expensive data. And even if they're not abroad, they don't want to take data against their data cap. So by saving some space and giving them a whole bunch more information, we've made Wi-Fi location much, much more available to all users. With that, I'd like to move on to some API changes. So I mentioned that we lowered power consumption.

And specifically, we were noticing a problem with a lot of applications in the store that wanted to run in the background for one reason or another, like fitness applications and driving applications, that-- let's say that a user is driving down to LA, and they get hungry. So they stop for dinner. OK, great. What do they do? They unplug their cord. They put their phone in your pocket.

But your app has been running this whole time. So the result is that you basically completely kill the user's battery. If they're lucky, while they're sitting at dinner, they hear their pocket talking to them. They pull out their phone. They realize, oh, this app's using on my battery. They kill your app, put the phone back in their pocket, and they can still make a phone call. But Murphy's Law says that that's not going to happen. So what it comes down to is we get this scenario that's just really, really bad for users because you're using location that's not actually helping them with any sort of their experiences. So we looked at this and we thought about this problem, we tried to summarize it. So basically there's a couple of key parts. First off, apps are running indefinitely. The next thing is that often the user is not moving. If we're getting the same fix time over time, it's not -- doesn't mean that the user actually is getting any benefit from still running. Similarly if the user, say, moves into a subway system that doesn't have any possible signal, then it's possible that we're just not going to fix. And then lastly, sometimes the user is just not even doing your activity anymore. That's kind of the clearest indicator that they're stopped. If you're not running anymore, you're in a car, or you're sitting on a couch, there's no reason to be running.

So we looked at all these problem points, and we basically came up with an API to fix all these problems. And we call that the AutoPause API. And specifically, what we can do is we can say, look, is your application in the background? If your application's in the background, The result is that the user might have forgotten about you. They might not be interested in you anymore. They don't necessarily-- they're not interacting with you directly. So that's a good clue that maybe you should be paused. But we're not just going to pause you for being in the background. We actually have a couple of criteria based on what you just saw. Is the user moving?

Are we fixing? Can we get a location for this user? And similarly, we actually can do some activity detection to say, hey, look, if you're a running application and you get in the car, the motion's completely different. We can kind of detect the two, and we can pause you just proactively based on activity type.

So what does this API look like? Well, for starters, you need to know whether it's on. And the answer is basically if it's on, if you're linked against iOS 6, we're going to turn it on for you by default. All your old applications will work as before, but we're going to turn it on by default. But we're going to give you a property that you can control to say whether or not this is a good idea.

Similarly, you're going to need to know-- you need to tell us what type of activity your user's doing. So we've got a property on the location manager now called activity type, which is going to allow you to set us-- tell us the activity type your user's doing. And so we've come up with three basic activity types that you could choose from. The first is vehicular navigation.

So your Maps application that's giving navigation or your TomTom or Navigon or somebody. Fitness applications. If the user's running, if the user's cycling, that's a good indication that you're a fitness application. And then lastly, everything else. Basically, those are the two most common types of applications that want to run in the background, so everyone else is kind of lumped into other, which just has some basic characteristics from both of them.

The next thing you want to do is, what are we going to do when we pause you? Well, what we're actually going to do is we're actually going to tell you that, hey, we've paused you so that you can respond appropriately. You could flush some data to disk. You could go ahead and tell the user. You can do whatever. Similarly, if your application is suspended because of a pause event, and then later your user launches your application to the foreground, we'll put you back where you were. We'll send you a resume notification, and we'll reconnect all of your location, and you'll start receiving location updates just by the user launching your app. Because again, you're not in the background anymore. Your user's actively telling us, hey, look, we're trying to use this app. So we'll put you back where you were. So with that, I'd like to invite up Mike Del Santo, who's going to give you a quick demo of how to use Autopause. Thank you.

All right. Thanks, Jay. Hey, how y'all doing? I'm gonna tell you a little about AutoPause, our new feature, our new power-saving optimization. And our goal for this feature is going to reduce the number of backgrounded applications that are unnecessarily requesting location updates. So what I've got here is your boilerplate fitness application. It's called AutoPause Demo. And as you can see, it's nothing more than a start button, right? And that will actually, underneath the hood, call start updating location. I've got a table view which will list the location updates as they come in, and then I have a map view which will plot the location updates. So for this demo, you can see that I'm actually simulating a location in our iOS simulator. This is considered our city run. So being that it's a fitness application, I thought it would be nice to actually see these being mapped as if you were running.

So the main point of this feature is that if you are in the foreground, core location hands off. We kind of say that it's up to the user to determine that they are actually tracking, so they know best. We'll remain, you know, uninvolved. As soon as the application goes in the background, that's when we start determining, you know, are these location updates benefiting the end user?

If I were to actually background the application while I'm running right now, we would say, yes, these are benefiting the end user. He's registered as his activity type is fitness. And ultimately he's probably using these. But let's just say that you were using my application here, and after your run, you got home and you were completely exhausted and you were like, thank God, I'm finally finished with that horrible run. So instead of actually actively stopping the location updates, which would be the wise thing to do, you just put it in your pocket or you put it on your dresser and you take a shower and you completely forget about that. Meanwhile, we are continuing to determine position estimates, and those are not going to be benefiting you if you are registered as a fitness activity. So to showcase this, we throw this into the background, and during this time, CoreLocation tries to determine are these updates actually benefiting the user. And in our case where we've stopped running, they are no longer benefiting the user. So after quite a bit of time, CoreLocation will issue you the pause notification. And what that is is it's the CL location manager's delegate callback. Location manager did pause location updates. So when we actually pause you... That means that underneath the hood, we've called stop updating location.

And besides that, we'll issue the pause notification, and then you know that it's your time to actually save data to disk if you want to or notify the user if you see that to be beneficial for your application. Once you're in a pause state, it's imperative to know that there are one of two paths you can take without actually interacting directly with the location manager again.

You can either bring the application back to the foreground, which will resume location updates where we left off, or you can kill the application, which will clear out your pause state entirely and then it is up to the user to actually start location updates manually. For this first case, I'm just going to open my app back up and you'll see that immediately CoreLocation determines, hey, this guy is back in the foreground. We had paused him. It would be really nice of us if we actually started updating location again on his behalf. So once we do that, you'll see that updates are coming in at a one-second frequency once again.

So to walk you through the code, I want to show you how simple this feature is actually going to be to implement. I have a location controller here, and that location controller is made up of a location manager and then maintains some state for the manager. You can see here that I instantiate the location manager the same way that I would have done in any other iOS release before this. Nothing new there. But what is new is the activity type. Now, we're asking you to help us help you. Please register your activity type. And this is because we're able to fine-tune our pausing algorithm and actually determine if your activity is being performed based on the context around you. And as Jay mentioned, a simple example would be if you're running and you go to a car, I mean, obviously, your accelerometer is not moving. Your arms are not moving your device anymore. So it's kind of an indication that maybe that they're going 45 miles per hour down a road, they're not performing a fitness activity any longer. So for my app, I've registered for the fitness activity. Besides that, we have the pauses, location, updates automatically. As he mentioned, we are going to opt every application into this feature moving forward. The only way-- if you, for whatever reason, feel that you've come up with your own power saving optimization, or you feel that you can do this better, you are welcome to opt out of it. But moving forward, everyone will be set to yes. And that's all there is to it for the location manager. We have the two callbacks.

location manager did pause location updates. So when your application does get this callback, it's your indication that underneath the hood, core location has actually stopped location updates on your behalf. So the wise thing to do is you know that you're in the background, so obviously you're on borrowed time to begin with. So it's smart to actually maybe maintain some state of your application. Here I keep track of my pause state and my location update Besides that, I thought it would be nice for you guys to actually see a local notification in the notification center. When we were paused, you probably saw immediately that the local notification was posted. And I do this for two reasons. One, so you all can see it here in the demo. But more importantly, it is your handle for bringing the application back to the foreground; right? So local notifications have this set alert action. Here I said resume. So when you actually go ahead and slide the alert action, back to resume, the application will take the foreground, and as I mentioned, we will continue requesting location updates where you left off. Last but not least, for the pause notification, I save the data to disk. As I mentioned, your unborrowed time, this is just a wise chance for you to actually store whatever you may need to use later. Thank you.

So we've also got the did resume location updates. When your application's brought back to the foreground, this is when we actually will, under the hood, call start updating for you, and then inform you via this delegate callback. So I want to clear out some internal state that I've kept for my location controller.

Remove any local notifications so that there's no lingering notifications in the notification center. Obviously that would be a confusing state for the user if they saw it running and the notification center still had some lingering. Please resume my activity. And last but not least, for this demo purpose, I actually post a UI alert view down here. Just so you guys can actually see underneath the hood what's going on.

So to run through this one more time, we are still in a tracking state now, so I'm going to push the application to the background. So core location is actually churning on every position estimate that we actually are going to give your delegate. And we're going to determine is this benefiting the user.

After some time, if you're no longer moving or if you're indoors and you're not able to get a GPS fix, we'll say, obviously, he's just draining battery, he's wasting the user's precious power, so let's go ahead and pause them. So you can see that we were issued the pause notification and I kind of missed it, but I wanted to actually note on the fact that under settings now and in the status bar icon, we've increased the delay timer from -- on the status bar icon, we've left it in the status bar there for 10 seconds. And under privacy, we've left it next to your application right here for an additional minute. And this is because we don't want it to be any mystery for your users that your application was using location. So now you have a clear indication that within the last minute or so, this guy was actually using location.

So as I mentioned before, if the application were to take the foreground, we would resume location updates for you. But if the application is killed via by the user actually killing it manually or if the system is under load and needs your resources and has to actually kill your app, we will not resume location updates for you. So that's what I'm going to do this turn around.

I'm going to kill the app. And you'll see the next time we launch the app, the app is launched with options, or did finish launching with options, as if it was the first time it was ever launched. So the user can actually go back and look at his last run and marvel at not being resumed when he wasn't hoping to be resumed, essentially. So... That's pretty much all there is for Autopause. A key reminder is please set your activity type. Help us help you. Let us stay completely informed of what you're trying to do. And other than that, we look forward to saving some battery life with you guys. Thank you.

Thanks, Mike. So Mike gave you a quick example of how you might respond to a user's--how you might respond to a pause event from us. And so I wanted to go over a couple of other ideas. So the first idea is that we're only going to pause you when we're actually sure that the user is not interested in your location data. So if you receive a pause event for us, it probably means you shouldn't be running because your user doesn't expect you to be running. So with that, the first--the easiest thing you can do when we send you a pause notification, don't do anything. You can log it to disk maybe if you want to keep a note for yourself while you're debugging. But what it comes down to is there's usually no action required. Your user's just not expecting any more activity from you.

The next thing you might want to do on an event is to do exactly what Mike described. If you're a fitness application and you're expecting to be in the background a lot, maybe you send a notification to the user or maybe if you've got their headphones in, you send them a quick little audible saying, "Hey, by the way, I'm stopping your activity because you're stretching now." Another thing that you might want to do, especially in the fitness app example, is just stop updating locations. You can go from pause to stop just by calling stop again. And if you agree with us that you agree that the user is no longer doing what you thought the user was doing, there's no reason to be running. If you're a fitness app and you're paused and you then stop yourself, the result is that when you come back into the foreground, the user can now view your old track and maybe start a new one. You don't randomly have data from like a couple days later being added to a really old track in the user's UI. It's not a good experience to necessarily just be paused and then resumed. Sometimes you do actually want to stop. But this is not going to be enough for everybody. So I'd like to talk about a couple of other responses that you might want to have. For 95% of you in the room, this is not the slide you're looking for. Please just ignore me. Go to sleep. Do whatever. It's after lunch anyway. So one thing you could do is you could actually just disable auto pause. As I mentioned, it's a property. You can just go ahead and set it to no. And we will just turn it off. You will be fully responsible for the user's battery and the user's location and that's all up to you. And maybe you want to do that.

This is tempting to you. I would like to suggest maybe two other approaches that are kind of a compromise on power. The first is consider the case where you're driving and the user has followed every single one of your turns as you're going down the street and you get a pause event from us while the user has temporarily stopped moving. Well, if you know they're still on the freeway and you know that they're still doing what you've told them to do, there's chance they just got caught up in traffic. So it's entirely possible that there's some cases where you might want to restart location. And we make this possible to do. You just call start updating location. And even if your app is still in the background, we'll give you a little bit more time to run and we'll think about whether or not you should be paused again. And so if your user starts moving again, we won't pause you. If the user still stays there, then maybe we'll send you another pause event. So it's kind of a way as a compromise to say, hey, look, I actually in this case know better than you. But here's a hint. If you've been telling the user to make U-turns for the past two minutes, maybe they're actually sitting in a restaurant and no longer driving and maybe we're right and you have no -- you don't actually know what the user is doing anymore.

One other idea is if you had an app that was just generically kind of wanting to log the user's activity as kind of a path or like some sort of activity, just generic, not necessarily fitness but just kind of, hey, where have you been in the world? It might be possible that the user's gone home for the night, you'd like to kind of pause temporarily and then start again in the morning.

And it's actually easy to do this, but it's always been possible. You could have just stopped yourself and then installed a fence. So geofencing would allow you the ability to resume yourself if you paused. Now, again, I really strongly suggest that you guys don't do this. I think that most users are not going to expect this behavior. If your app runs almost indefinitely as far as a user's concerned and every other app in the store pauses, you're going to look bad. So I would strongly consider trying out AutoPause as it is. Just tell us your activity type, see what it feels like, and then if you have problems or you want to tweak performance, you can go and kind of do this. So for the rest of you, just most of you can just forget this slide.

So with that, we have a couple of other API changes that we've made in iOS 6. So the first off is sometimes it's useful to us to notice that, hey, look, you're not necessarily handling location updates as quickly as we're sending them to you. So rather than waste CPU cycles sending you messages, what we might actually do is we might want to coalesce a handful of messages into one, just give you an array of location objects. So with that, we've actually got a new delegate callback method that just takes an array, they're just chronologically ordered, the last one is the newest one. So if you fall behind and we actually send you a couple, then what you want to just do is look at the last element, plot that on the map and then just throw away the rest because your user is not there anymore.

So with that, we've actually deprecated the old API. If you're targeting 5.1, obviously, you need to still use this API. But on 6, we actually, if we see both, we'll only call the new API, so your new delegate. So the way that you want to handle this if you're trying to do 5.1 and 6 is just implement the old delegate, pack up the object we give you into an array, send it to your new delegate, and implement everything in your new delegate. And that will allow you to run on both platforms.

The next thing I want to talk about is kind of a quick overview of privacy on iOS. So as you know, iOS 6, we're doing a whole bunch of privacy controls for all of the user's personal information. Now, location has always been considered personal on iOS. And so it's always been possible -- whenever you've tried to use a user's location, we pop up a dialogue that looks like this. So we tell the users, hey, this application is trying to use location now. And then you tell the users, hey, this is why I want access to this user's private information. And if you give them a compelling enough reason, they'll say, okay. If you don't give them a compelling reason, they'll say, go away. And if they do this, you still want your application to work. So keep in mind that you might not always have location because the user might not trust you with it. Or maybe they would just prefer to type in an address and let you geocode it and then find something. Or maybe they just want to go to a region in a map that they're not actually physically at and use your data that way. So I guess one thing to keep in mind is that it's entirely possible that the user will prevent you from using their actual location.

So another quick recap is that the user is always in control. So they can turn off location globally. They can see which apps have asked for location. They can specifically go in and say, hey, look, this application's used location within the last minute, as Mike pointed out. Or they could say, hey, look, this application's got this little hollow icon. What is that? This is actually our geofencing icon. So nice little hollow. It looks like a fence. Basically, if you start region monitoring, we'll go ahead and tell the user this is that, hey, look, eventually your location will be revealed, but we're not actively doing it right now. And then lastly, for user's convenience, if you've used your user's location within the last 24 hours, we'll go ahead and tell the user, hey, by the way, this app's used your location just so you know, if you're just kind of casually presuming looking at settings. And so if a user's confused by the location arrow flicking on, they have no idea what's going on, they can come in here and they can say, hey, look, this application was running.

And they can decide to say, hey, maybe I don't want that. So again, make sure the user expects location to be used by your application in a meaningful way. And that's the best way to keep these switches on. I guess one last little thing is that the status bar, as you know, is a summary of what's going on.

So solid if we're using location, hollow if it's just nobody's using location but there are fences installed and then nothing if everything's powered off completely. So with that, I guess a quick going into now how to actually get the user's permission. So for starters, basically how do you get this dialogue text up there? So with iOS 6 and all the other privacy changes we've made, we took the information and we actually put it in the user's info.plist.

And location is done the same. So there's now a new key in your info.plist called NS location usage description that basically acts just like all the other privacy controls. If you have an info strings file, you can localize this just fine. And it's the preferred way now to express your intent to the user.

Similarly, 5.1 still uses the purpose string. So 6 will still support it as well. But if we see both, we'll prefer the info.plist string over the purpose string. So you might actually want to read the info.plist string out yourself and set it to the purpose string if you're targeting 5.1. With that, I'd like to move on to talking about basically performance tuning. So I'd like to start off with two myths that I'd hope to dispel. I saw an app in the app store recently that actually told its users that if you want to get a location fix in this application quickly, you should launch maps first and then launch my app because maps gets location faster. Maps uses the same API that you guys have access to. So if maps is loading it faster, it's a function of what maps is doing versus what you're doing, not what we're doing under the covers.

And the reason why maps loads location faster is because they're constantly engaged with the user. They start off, they take a high level cell fix that looks like this. They know you're in the Bay Area so they start bringing the map there. You get a better cell fix and they start bringing you a little bit closer. And eventually you get a Wi-Fi and they zoom in a bit more and eventually you get GPS and you get this nice little pulsing dot that says, hey, look, I'm out in front of aisle one. And so if maps is doing this, engaging their users up front, maybe you could be doing the same thing. So consider the case where you're just a restaurant app, and I just went ahead and mocked one up here using maps, right? You get to the Bay Area, you could say, hey, look, here's some awesome restaurants. These are the four best restaurants in the Bay Area. Any user that ever flew to San Francisco would want to drive to one of these restaurants. And you could just make it available on the device for them.

Ready to go as soon as you get any sort of location. Or maybe you get a little bit better and you actually, say, have a couple of bookmarked restaurants the user particularly likes or hasn't tried yet. Maybe then later on when you actually get a Wi-Fi fix, that's when you actually care, okay, I'm in this neighborhood, maybe now I should go download some new data and say, hey, look, if I'm at Apple campus, there's BJ's and there's Cafe Max, those are your two dining options. And then lastly, GPS, maybe you could tell me how to walk to Cafe Max if I don't know how to get there from my office already. But the point is that most of these scenarios don't require a GPS fix. So if you're sitting around waiting for a handful of seconds just spinning or showing a gray background, your users are bored and they might click out of your app because your app is not providing them functionality. So engage your users up front. So with that, I want to talk about another myth. Now, the myth is basically that Wi-Fi -- you should turn off Wi-Fi in order to improve location accuracy. And I think this comes about when you've got a fitness application that's considering a a user's run track, and all of a sudden, you get a Wi-Fi fix that's a very low accuracy, and it kind of pulls you off that track. Well, the answer there is to filter it, and the reason why you want to do that is because turning off Wi-Fi doesn't improve location accuracy. Again, this is our drive-- this is an example of our drive test in San Francisco. This is what you get with just GPS, nothing else.

If you turn on Wi-Fi, even if you're running or if you're in a car, you get this. And if you're in a car and you've got Wi-Fi on, you're gonna get something like this. So it's really not beneficial to your users to tell them, "Hey, look, turn off Wi-Fi. Just look at the horizontal accuracy of the position we report to you and just filter it out. Say, 'Hey, look, this is not useful to me. I'm just gonna ignore this one location and wait for the next one.'" So again, user experience, no Wi-Fi, with Wi-Fi. Leave Wi-Fi on. Thank you.

I went for a run in San Francisco, just kind of generically wandered around a couple of different streets. And I ended up with a location track that looked like this. Now, this is San Francisco, you know, location is not necessarily the best, there's all these skyscrapers and this and that and the other thing. Well, actually, I left my iPhone at home. I strapped an iPod touch to my arm and I got this track. An iPod touch doesn't have a GPS. So this data is It's purely Wi-Fi using the new tiles.

So if your application thinks that it needs GPS, you're really kind of ignoring a whole body of users that could really benefit from your application without necessarily having to pay for an iPhone or a nice iPad. So with that, let's kind of summarize these two scenarios and think about what we can do to kind of improve this now that you know that these things don't make-- that these myths are myths. So let's talk about supporting an offline user experience. Basically, if you support -- devices sometimes travel into poor coverage areas. You can't always assume that you're going to be able to get reliable Internet data.

Similarly, even if you have data, users don't necessarily want you to constantly use their bandwidth. Because using bandwidth also drains power. So if you wanted to target an offline user experience, you can get situations like, say, the restaurant case, where if you were having that data already on the device, you're instantly responsive. user thinks you're ready to go even though you're quietly in the background trying to madly catch up and figure out what's changed and whatever. But the view they last had, you could present to them already. And lastly, if having a really high quality app is not interesting to you, how about just selling a couple extra million copies of it? So, I mean, we -- it's just something to keep in mind. And now I made light of this last point, but this one is a little bit more serious. Apple takes privacy information very seriously. all of location information that Apple maintains on your device, we always encrypt for your users. We make available data protection APIs that are available to you. So if you're writing data to disk, I would strongly encourage you to look into the data protection APIs and maybe consider encrypting the data. It's basically transparent to you. We handle all of it for you. You just have to write to a file and we just take care of the encryption. So it would be a good idea to protect users' data like we do.

So with that, I guess I want to couple of other things. So we introduced this great new autopause feature. Who's going to take advantage of it? Well, let's say that there's a couple of reasons you're going to run in the background. Navigation. Fitness. Maybe you want to get reminded when you go somewhere.

Or lastly, maybe you just, let's say, let's loop everything else into an automatic check-in app. So maybe it's the, hey, look, I'm at this bar. Maybe you should come find me or everything else. So it's really easy to run in the background on iOS. All you have to do is you just say, hey, look, I want to run in the background. Here's my UI background modes, set it to location, and if you don't speak random keys, then this is what Xcode will show you. And so you can just run all the time. It's easy. But there's really no reason to do this unless you're a fitness or navigation app. These are the only apps that actually do want to run in the background for minutes and hours at a time because most other apps just want to have the appearance of running in the background. Reminders doesn't actually care when the user is moving around. They only care when you get to work or when you get home or do something that's interesting to reminders. So they use the fencing API. So basically running all the time really is just -- yes, auto pause will help you save power, but it's really just most cases don't need it. So with that, I would like to suggest the alternative which is that you should just run when necessary. So if you register for significant location changes, the result is that you can tell us, hey, look, I kind of want to know when the user is moving around. So if the user, say, moves to a different city, I'll get updated about it. And if the user says, hey, I don't want to use this feature anymore, you can turn it off in your app. And you can handle it just like a regular location event. But meanwhile, you're running in the background. You get launched occasionally. You can handle one piece of data, store it, send it to a server, do something interesting with it, and you can shut back down. You're not using the user's battery just to track them, just attract them constantly.

Similarly, fencing. If you wanted to go ahead and monitor a specific region, you could just tell us, hey, look, I want to monitor this region, or I'm no longer interested in this region. And we'll tell you, hey, look, the user's now gone to work, or the user's now left for the day. And it's really easy to actually install fences that are relevant to your users. You'll have the appearance that you're running when the user needs you to be running, but you're actually not most of the time. And then lastly, something to keep in mind is that you can always tell UI application, hey, I want to run longer. So why not just go ahead and begin a background task and then start location updates, wait for the level of fix that you want, turn it off, and then you're done. So with that, I'd like to suggest a model for starting responsibly. So let's consider, again, the automatic check-in app. What do you want to do when you want to start location? Well, you want to make sure that you can run for a little bit of time in the background.

know, springboard might give you ten seconds. With this, you can grab, say, five minutes. And then if springboard says, hey, look, you're out of time, you go ahead and stop location. But five minutes is still a really long time. So what you should actually do is you should start some location -- you should start a timer for you. So let's say that you had a method in your function called start location timer that just started a timer saying, hey, look, I'm trying to get a location fix. So with that, what you could do then is you could actually when that timer fires, say after 30 seconds, maybe a minute, you could just shut down location yourself. Say, look, for some reason I'm not fixing, I'm just going to turn everything off. And that's much better than waiting for us to pause you because we're, again, we're viewing it very conservatively. And so we're going to take longer than a minute or two to be able to determine that the user's not actually getting anything useful. So you can do it much better with your own timer. Then once you've, once you've set up the safety mechanisms, all you have to do is start calling location updates like you've already been doing.

And then maybe go ahead and save a little bit of state for yourself saying, hey, by the way, I'm running. So in that case, if you were, say, now going to implement a significant location change handler, again, it's just the same handler as before. So this is the new one. Location manager did update locations.

And in this case, let's say you launched due to an SLC event, a significant location change event. The result is that you could look at that location that we gave you, take the array, grab the last object, it's the most recent one, and you can say, hey, look, is the accuracy of this thing good enough for me? If it's too large, then maybe I don't really care that I'm in this city. I actually was trying to figure out what bar I'm at so that my friends can come find me. So just go ahead and say, look, it's not good enough.

If a location's already started because you're keeping track of that, you just sit there and wait. Eventually a better location will come in and you can respond with that location. Otherwise, you can go ahead and start location. Now, if you're launched to an SLC event, you've got a handful of seconds to do whatever you need before you get suspended. Since you already wrote the start location function, now we're going to go ahead and grab that task assertion and we're going to get you some more time, which is very useful. Now eventually, sometime later, that better accuracy came in, Wi-Fi kicked on or you got a GPS fix and you now know exactly where the user is, you're ready to tell the world about it, update the view or update your data model or send it to the server, do whatever you want. And then you're going to implement your own stop location method. I've omitted this from the sample, but your stop location event is going to do the exact opposite of your start location event. It's going to stop the background task assertion, it's going to stop turn off the location timer, and it's just going to stop location and set the flag to none. So it's really easy to run in the background for short intervals of time without using the UI background mode's key, which is just really -- it really will allow the user to run better in the background. Autopause is really just designed for the apps that actually are trying to run a long time in the background. I'd like to give you guys a quick summary. So what we've done this year is we've made horizontal accuracy better than ever. We've made location more available than ever with both Wi-Fi on iOS devices and making APIs available like region monitoring on OS X. And then lastly, we've made power consumption better than ever. But in return, I want four things from you guys. First off, I want you to run only when you're needed. Autopause is great, but consider SLC and consider region monitoring. They're powerful APIs that will let you run when you actually intend to. Then I want you to tell the user why they're using it. And I want you to use the new NS location usage description key. And I want you to honor that contract. Don't let your users be surprised by the arrow popping on. Actually just do what the user expects with their location.

Next, specify user's activity. If you're being a map application, tell me your other. If all of a sudden the user gets in a car and you start giving them driving directions, flip your activity type to vehicular navigation. Keep me up to date about what the user's doing, and I can help make sure your app gets the best performance out of AutoPause. And then lastly, leave Wi-Fi on. Don't tell your users to turn it off. Let your users get the best location experience possible. I'd like you to point to a couple places for more information. Paul Marcos, [email protected]. He's a great point of contact. He's definitely helped me with these slides, and he's really been a good resource for just interacting with you guys. We've got some documentation online. We also have developer forums. Feel free to check those out. If you've got a time machine or you just go ahead online later, you can go ahead and watch the Using MapKit app 'cause many of you will want to use location by presenting it to the user using maps. So I would recommend downloading that after the sessions become available. Core Motion is another great way to provide context on your device. Knowing what the user is doing with your device is almost as powerful as knowing where they are in the world. So go ahead and check out Andy's talk on Friday. So with that, I'd like to thank you for coming.