What’s New in Core Location

Session 307 WWDC 2013

Core Location offers a variety of ways you can find out where your users are and when they are on the move. Hear an update on changes to Core Location and dive deep into the new world of beacon regions. Leveraging Bluetooth Low Energy, iBeacons open up a whole new dimension in region monitoring. Gain a practical understanding of how you can efficiently create beacon regions for important locations so your app can be alerted when users enter them, and techniques for detecting proximity to physical objects.

[ Silence ]

[ Applause ]

Jay Bruins: My name is Jay Bruins and I'm a Core Location Engineer and I'm here today to share with you some exciting new changes that we've made to the Core Location APIs and so let's get right into it.

We've got a number of things we're going to cover today.

The first thing that we're going to cover is changes related to the new Multitasking Behaviors.

And so some of the multitasking behaviors change the way location work and so we're going to cover those today.

The next thing I want to dive into is going to be Creating Fitness Applications.

Many of you guys already have applications in the store that allow a user to track their fitness but, with a couple of changes you can actually get much better battery life.

And lastly, we've got some exciting new region monitoring changes today that I'm happy to share with you.

I'd like to start by saying this is not a review.

If you're watching this online you might want to pause and go back to last year's video, which is going to be much more basic.

This review today I'm going to move very quickly.

So, if you're in the audience stick around.

You're going to experience our exciting new features but you might want to kind of review our documents online to get yourself grounded a bit better before diving into Code.

So with that, let's start talking about the Multitasking changes and how they relate to your location application.

So, one thing to keep in mind with the new multitasking UPIs is that we've allowed the user to take control over multitasking behavior on iOS.

So, with that the user can actually disable multitasking across the device.

Similarly they can single out your application to say that I don't want it to be running in the background.

Usually it's to save power or some sort of conception issue like that.

And lastly, they can temporarily override multitasking by quitting your app from the app switcher.

And if they do this, this is a signal to us that they're not really interested in the features that your application provide for a period of time and they'll manually launch their application when their interested in receiving your functionality again.

So, with that let's talk about the Core Location APIs that are affected by this multitasking ability.

Specifically, continuous background location.

So, if you're a fitness application or you're providing turn-by-turn directions and you want to continue running the background with the power on we're this is going to be affected by the switch.

Similarly, if you're using significant location change to provide overall day-to-day tracking of the user or if you're using fences to provide notifications of arrival or departure, these APIs are disabled in the even the user turns off Multitasking for your application.

So, we have a couple of recommendations for you and these really dovetail with the recommendations we've always been providing you with regards to authorization on the app.

Be clear about why you're using Location.

These goes beyond just specifying NS Location usage description key inside of your infoplist.

What we'd actually like you to do is use location in response to users interaction with your application.

Start location when the user presses the location button or does a search and they need to know where they are.

Be selective about using location.

If you turn off location and the user sees that you're responsibly turning off, they're more likely to trust you with their location and they're more likely to leave Multitasking enabled.

Similarly don't start on every launch.

Realize that your application can launch for a number of reasons, including into the background.

And so if you're launching location, if you're starting location every time you're running, you're just going to guarantee that you drain the user's battery.

And if we're talking about launching our app proactively to do fetches in order to have a fresh UI, we're going to be throttling you more aggressively, if you're using location.

But that's not to say that you shouldn't do it.

It's just that you need to be cognizant of these changes.

And especially when you're fetching proactively understand that the location that you're going to achieve for the user might not actually go to a user's specific experience because the user might choose not to launch you.

And so with it, turn off as appropriate in the background.

If you have a location that's good enough to hit your server query or a certain amount of time has passed and you're just not going to get a kind of quality location because the user is in a bad location, then turning off location will really allow you to save battery, prevent being throttled and overall have the best user experience possible.

With that we actually made some changes to continuous location behavior in order to help you avoid killing battery.

So, to remind you this API is what you get when you specify that you want to be a Location background app.

And if you put this in your infoplist when you start location we will keep we keep the device awake as long as you can tune in to use location.

But in iOS 7 because of these extra launching tasks we actually don't want to start in the background.

We see Continuous Location as an extension of the foreground.

So, a user starts navigating to a location and then they suspend their application and they lock it and they put it on their dashboard.

Turn by turn should continue but you shouldn't start in the background.

Similarly if they go for a run you know the user had an opportunity to start your app before they switched to their music player.

So, starting in the foreground is not that stringent of a requirement.

We realize that there are a handful of applications that are trying to do day-to-day tracking using significant location change.

And for those applications we will still honor the background modes key and keep the device awake when you are using location.

But in general, if you start Location in the background we'll simply leave we'll give you location services as long as these are running, but we won't guarantee that we'll keep you running and this is the best tradeoff for power and user satisfaction.

With these changes however, it's possible that the user could tell you that hey, I'd like to get directions to dinner and tell us, I don't want any applications to do multitasking.

And so, in that situation it would be a good idea to check a new property on the UIApplication instance, backgroundRefreshStatus.

If your status is currently available then APIs will behave exactly as expected.

However, if it's denied this means that the user has chosen that they don't want your application to be running right now or running in the background I should say.

So, as a result we won't launch you and we won't allow you to continue running indefinitely.

There's and if this happens and you have specific indication from the user that you actually they do want your app to function it might be a good idea to pop a dialog and tell them to go to settings and correct their situation so that they can get the app functionality that you want, that they want.

Now, there's one other option and this is restricted.

And this is if parental controls or an enterprise profile were installed and Multitasking is locked off.

In this case, there's not really much point in telling the user to go to Settings because there's nothing that they're going to be able to do inside of Settings.

So, instead please have your application degrade gracefully, gray-out some menu options or just hide them completely and don't tell them that hey, there's these great features that your phone can't do because your system administrator locked it out.

Lastly, if you're running into the background at the point that a change occurs we'll give you a notification of this fact and you can check this.

Now that's one caveat and that is that this API is actually not available in the first seed.

So, the second seed which is going to be available shortly will actually have this API in it and that will allow you to start tuning your applications to provide the best user experience.

With that, let's talk about creating a fitness application.

As many of you already know because we've gotten many great examples in the store, creating a fitness application is easy.

Start allocate a locationManager, set yourself as the delegate, specify the fact that you're a fitness application.

Now this is a step that not everyone is doing and I would highly encourage you to do so because it tunes the way that auto pause works.

So, if your user is running around a track and it looks overall at a high level view like they're moving about 100 yards, stopping and moving about another 100 yards, now this is in an oval.

But if you're in a car that's not a lot of movement and so we'll assume that if you were navigating in a car that actually the user would rather pause their activity right now because navigation is not really relevant anymore.

But if you're in a fitness application, clearly the user is still running and we should keep going.

Similarly if you specify fitness activityType.

When we're considering mat matching scenarios, we're far more likely to leave you meandering around a park and less likely to snap you to a freeway if you tell us that you're a fitness application.

So, doing this will help tune Core Locations behavior to maximize your fitness application's quality.

And, of course, the most important step start location updates.

At this point you've got an application that's happily collecting a location and its going about its business and your user is usually pretty happy.

But it's also starting to actively drain the user's battery life.

To understand why, let's look at how GPS works on an iOS device.

So, inside any iPhone or any device that's got a GPS chip there's actually a specific chip that's sole purpose is to decode signals from a satellite and encode them as locations and deliver them to the device at which point we can deliver them to you via the Core Location APIs.

And this is an ongoing process that occurs whenever you've turned on GPS and it consumes a certain amount of battery.

Beyond just the battery that's consumed by the chip itself, the phone stays awake.

So, if we had a way to turn off the device and let it sleep while the GPS was continuing to function and coalescing updates into a single coalescing updates on that chip then we can end up leaving the device asleep.

And now if the user pulled the device off their arm and they wanted to check the status of their run and woke up the phone, we could deliver all of the location updates in one deferred updates to you.

And it turns out that if we leave the phone of but leave the GPS on that roughly equates to up to 40 percent power savings.

So, that's basically the difference between going for an all day hike and having a completely dead battery or getting back to the trail head and being able to call your family member and ask for a ride home.

So, this is really exciting.

To come with an API that would work and allow us to defer as maximally as possible, first we had to come up with what an idealized fitness application looks like.

And so for us, and we model this basically off of apps that are in the app store and usually the script goes something like this.

User turns on their phone, starts running applications.

You give some sort of notification being like hey, I've started the run.

And now this is where we'd actually like the phone to go off.

And so we realize that some users like to be motivated as they're running so that at some point later there they've gone a certain amount of distance.

It would be nice if the phone could wake up, know that they've gone a mile and say congratulations you've made a six minute mile.

Keep up the good work!

And again, going back to sleep and similarly sometime later say, hey look you have 45 minutes remaining in your workout, keep it up.

And then do this a couple more times and eventually know work out's completed.

You've gone 9.6 miles, awesome.

So, if we could do this and if we could defer location updates during this period then we can actually save a significant amount of power.

And so, to achieve this we left the API more or less alone.

You set up your fitness application just as you did before.

The magic is going to come in from how you handle locations from us.

So, if you receive an array of locations inside of the DidUpdate Locations Delegate Method when you update your model with your run information this is the model that you guys have written that's going to keep track of how fast they're running, how far they've run and be able to plot it on a map.

Do this step as you've done before, but now if you're not currently deferring location updates go ahead and query that model to figure out how much further you have until the next goal for that user the next time you want to motivate them.

And similarly you might have a time-based motivation.

So, let's say you've got a date that's you're next audible that you want to give and you compute how far in the future it is.

Now if you tell your locationManager that I'm allowing you to defer location updates until the user has made it this far or this amount of time has past.

This is the clue to us that we can sleep the device if possible to save power.

And the last thing you need to do is keep track of the fact that you're deferringUpdates because this is useful for your application to know.

When your event finishes, when the users reach their goal we'll send you a notification to a new delegate method DidFinishDeferred updates with error.

And in the normal case this is not a problem.

We just have to mark the fact that deferred updates are completed and will rearmor logic for the next time so that the next goal can fire, the next goal can be scheduled and fire.

Now, of course, there's a handful of errors that we could return to you in this situation.

And so I'd like to take an opportunity now to go over a couple of those reviews to help give you a better understanding of how this API is working under the hood.

So, the first error that you could run into is NotUpdatingLocation.

Needless to say its impossible for us to defer location updates if there are no location updates.

So, please remember to startUpdatingLocations before you defer them.

Similarly, if you don't specify that you would like to use a GPS, if you're using a much less accurate request for location, we don't have a GPS chip that's going to be running and so we have no way to offload location to it.

Quite frankly there's a good chance that if you're not using GPS that you're already saving a significant amount of power.

So, this is a GPS technology.

So, to put your desired accuracy back to the default value and just leave it alone in the first place and specify best.

And lastly it's possible that you've told us that you'd like to filter locations via the DistanceFilter property.

And quite frankly us collecting a significant number of locations and then deliver it you all at once.

If you're not interested in most of them is it really beneficial.

So, to use this API you need to specify that you don't want a distance filter or just leave again the default value.

So, these three errors once you've established your application really shouldn't ever crop up again.

If they do, it's pretty much a programming error.

Normally, we would like to assert in the case that you've got a programming error so that we call your attention to it as fast as possible.

But because these properties already existed and it's possible that your code's already using them, we didn't want new assertions to pop up in your code.

So, inside of your UpdatesDidFinish, the DeferredUpdatesDidFinish delegate callback consider throwing your own assertion so you can call your own attention to it.

That way when debug builds you can iron out these issues and your users will never see it and we can maximize battery life.

Now an error that you actually can get that's normal is DeferredCanceled.

This simply means that you disallowed deferred updates and if this happens while we're currently updating we give you a callback saying hey we're done because you told us we're done.

But it's also possible to get a cancellation event if you reschedule deferred updates with new parameters.

And the reason why is because this is a fully asynchronous API.

So, if you're attempting to tell us hey, go ahead and change the parameters by how far I want to run, at the same time we're trying to tell you, by the way, you're previous criteria was hit.

Now you have an impossible situation where you can't know whether or not we're telling you hey, you finished the new one or you finished the old one.

And so to resolve this issue, you will get exactly one callback for every call to allow DeferredLocationUpdates.

So, if you're already deferring and you call either disallow or allow you will get a cancellation event.

And again assuming that we're not already in flight telling you that you hit your exit criteria.

So, if you look back at the sample that I provided earlier this is why we're keeping track of whether or not we're deferring location updates.

Because if you're not doing this and you're constantly rescheduling us you're getting spurious cancellation errors.

And worse than that you're causing us to recompute when the device is allowed to sleep, which basically is just going to keep pushing that date out into the future and there's no guarantee that we'll ever sleep and there's no guarantee you'll ever get power savings.

So, keep track of whether or not you're deferring updates and know that cancellations can occur because you've told us to change something.

Another error that you can run into is kind of a general catch-all error.

It's specifically saying that DeferredUpdates failed.

Now the easiest way for you to get this error is simply because you're trying to defer updates on a platform that doesn't support this.

So, if you don't have a GPS, for example, there's no way that we could possibly defer updates to the GPS chip.

Before starting DeferredUpdates if you check to see whether or not it's available this will save you again spurious errors.

This can actually happen under real circumstances.

Consider the case where GPS simply isn't available.

Usually this can happen if you start a run inside your apartment and you haven't made it back down to the ground floor to go outside.

The GPS simply isn't ready yet.

It's not fixing so if you try to tell us let me know when the user's gone a mile, and we don't have a solid start point that we can agree upon then we can't tell you when the user's gone a mile.

So, we'll go ahead and give you a deferred error.

Similarly along the course of their run you can have a minor hiccup that stops location updates.

This could be moving through a tunnel or any other temporary problem.

And so in either of these situations the simplest thing to do is simply to retry the next time we give you a location update.

Because if we can compute a new location update there's a good chance that we've already solved the problem that caused this issue and so it's a good time to reschedule.

So, if you look back at the sample code this is the reason why we defer location updates from within the location, didUpdateLocation delegate method.

And so if you use this as your entry point into the API you've already armed yourself to retry when it's probably most appropriate.

And you're not going to constantly spam us with deferred updates just because the previous one failed.

A couple other notes on this API.

The first is that we actually deliver LocationUpdates immediately in the foreground.

If the user is actively looking at your device, their own device, then there's no way for us to sleep the device because the device is on.

Similarly if they're looking at your application there's a good chance that they actually want to see your traces being drawn in real-time on their map.

And so we're not going to penalize you for that and actually we'll keep track of your foreground and background behavior for you and guarantee that as long as you're in the foreground whatever we're going to temporarily ignore deferred updates and just keep giving you live ones.

And when you back into the background we'll gladly try to sleep.

Now distance is completely optional.

If you don't care about how far you want to go but you just want to tell the user how far they've gone every fifteen minutes you can just leave the distance field off by specifying that you want it to be the maximal distance.

Similarly if you want to motivate people just by distance and not by time, you could specify that you don't care about time.

And, of course, together these are optional these are both optional so the reality is that if you specify a max for both fields we'll run as long as we are technically capable of running and then when we run out of memory on the chip we'll wake up temporarily, give you the current location updates that we have and then go back to sleep and keep going.

And we can rinse and repeat this until the next time that your user the next time that your user launches your application and then you decide, hey I want to defer I want to cancel deferred updates by disallowing it.

And lastly, this is actually available starting with iPhone 5.

And this is why we actually weren't able to talk about this last year.

So, it's actually available starting in iOS 6.

So, if you're curious about targeting your APIs against 7 and 6 this API is already available; go ahead and try using it.

So, with that I'd like to move on to a couple of New Region Monitoring Features.

The first feature I want to talk about is solving a little bit of a problem; it's a minor problem where let's say that your user decided that they wanted to monitor for arrival at a particular location.

Let's say and you already have a Placemark for it that you've already done a Geocode for.

So you take the region out and you start monitoring for it.

That's all pretty simple, but let's say that I was trying to remember that tomorrow when I get to Mascone Center that I want to remember to talk to somebody.

Now, if I do this then the result is that when I leave Mascone tonight my application is going to launch, it's going to run.

It's going to realize this location update was not really relevant to me and then go back to sleep.

So, it would be nice if we could save that step and allow you to specify that you only want to be notified on entry and you don't care about being notified on exit.

And so by separating these two entry criteria or by separating the notifications between exit and entry we can launch your application less often which will allow your device to sleep more, which is good for your users.

And these properties that are hanging off of the CLRegion object and if you specify them before telling us to monitor then we'll go ahead and honor what your request is.

And they both default to yes.

This is for backwards compatibility and just because it's kind of a reasonable default value when you haven't told us anything otherwise.

Next, another Region Monitoring tweak that we've made is to address specifically the case where you're trying to monitor for a user's departure from a particular location.

Let's say you want a temporary reminder saying hey, remember your car keys.

That way if you get six blocks from your friends house and go find your car you don't you actually can unlock the car as opposed to waiting and having to go back to their house.

So, this relatively easy to achieve, assuming you already have a recent location then you can construct a circular region around this user's location.

And, of course, you can use the new properties too to say that you really only care about exit.

But, once you start a monitoring for this region, Location will go off and try to figure out where the user is.

Now, depending on how long ago that last location was and how fast the user is moving, it's entirely possible that at the time that the fence initializes your user has already left their friends house at which point there is no exit notification to give you, because there is no exit event.

It's simply that we started outside the fence.

So, in iOS 7 we're providing a new delegate method.

LocationManager did determine state for region.

Now anytime that we determine the state for your region we will call this method and if you say compare the fence identifier against the departure fence and then check to see that that state is outside, it doesn't really matter how you got here.

If it's a departure fence you've already departed.

It could have happened before the fence monitoring started.

Now you what the state is and you can tell your user about it.

This delegate method is available on Location.

This is the delegate matter method that if you implement we will call and we'll call it whenever your application is already running.

We won't relaunch your application for all of the little details, but we will gladly tell you about the state for a region in detail as long as you're currently running.

And there's three possible states.

The first is the fact that you are inside the fence.

Obviously the other option is outside the fence and the third option is simply we don't know.

And usually this happens when your you've just installed the fence and so we haven't had a chance to start monitoring for it yet or alternatively it could happen if the device was rebooted because we don't track we don't persist where the user was.

If you reboot the device we temporarily lose the state of all of our fences and we have to reestablish ourselves.

This is why a Mac Book Pro if you shut it off and then you wake and you reboot it inside of a new location your fence won't fire.

It's because we don't secure we don't save your location information to disk.

So, with that there's one more thing and that is that this is queryable.

So if at any point in time you're curious to know whether your fence will fire and try to figure out which side of the event criteria you're on, you can ask us for the state of the region that we're already monitoring and we'll tell you.

This is particularly useful if the radius boundary where the user is and where the center is and the radius in a straight line suggests that you're inside the fence.

But if the user has been moving inside and outside the fence every couple of seconds we're going to coalesce those updates into something that's a bit more filtered and much more reasonable for the user so they're not constantly being spammed by new notifications.

So, in that case it's useful to query us to know what the current state is so that you can decide whether or not so that you can be in sync with us.

So, we'd like to move on to talk about a case that many of you that have retail shops are familiar with and that is the idea of basically how to interact with your user in a meaningful way while the user is at your store.

So, to do this, I want to talk about my side business, Jay's Donut Shop.

Now, it's a good point in time to remind you you're all under NDA which means that you can't tell my boss that you've been moonlighting.

[Laughter] So, hopefully my store has been quite successful lately.

I've got a lot of stores in a lot of locations.

And so I'm looking to expand and the most obvious choice for me is build an iOS app.

It helps that I actually know something about iOS and I can familiar with this so it's not that hard.

But engaging my customer in their store is useful.

You know knowing where stores are, what they're hours are, what nutrition information each donut has that's useful information that anybody could have.

But actually coming up with a rich experience when my user's already in my store and want to be engaged with my donut shop is really cool.

So, my first prototype for this experience was resolved around welcoming my customers to my shop.

Being a location engineer I already know that we have region monitoring in API.

So, I took my first shop in Cupertino and I started monitoring for that region.

Now anytime I showed up at my donut shop I got a notification saying, welcome to Jay's.

Well that's great but let's go ahead and expand it out to all my other stores.

So, we first installed a fence in San Francisco and then, of course, there's a shop downstairs and then there's a shop over in Twin Peaks and then there's one in San Jose and Los Angeles and New York and Denver and quite frankly this is both tedious and at some point we hit a wall and we can't actually monitor for all of these regions.

So, this is not going to work.

What would be nice is instead of monitoring for a region on the globe we actually monitored for what we're actually looking for, which is Jay's Donut Shop.

And so conceptually this is what we would like to achieve is just specify that whenever I'm inside of Jay's I'd like to know that I'm inside of Jay's.

And so to set out to build this core location team first looked at the actual physical store.

And inside of every store there's a glowing employee sitting behind the counter saying, "Welcome to Jay's.

Have a donut."

So when we looked to build something in the virtual world around this we wanted something that approximated this behavior and we noticed that a lot of stores already are switching their cash registers to iPads.

So, wouldn't it be nice if there was a way for your iPad to communicate with your customer's iPhone to tell them they're inside of Jay's Donut Shop and for your application on their phone to pick up and give them an immersive experience.

Wouldn't it be even better if instead of saying you're inside of Jay's to actually be able to encode some extra information like you're inside of the Cupertino store, try an apple fritter.

[Laughter] So this is what we set out to build.

And to do this we came up with a concept that we're calling iBeacons.

And so with an iBeacon take a Bluetooth device like an iPad and if we set a field around if we start advertising a particular packet from that Bluetooth device and we can basically end up creating a field around the device that is roughly a circle and if a customer walked by the store and then entered the store with their own iPhone our iPhone could see this Bluetooth low energy field and know that I'm inside the store and change its behaviors based on that.

And similarly when the user leaves that store we can know this and we can have an exit notification as well and this allows you to build context around multiple places.

You know any store, any Jay's store is roughly equivalent because each one has a beacon.

It doesn't matter where it is in the world.

And so going back to code, this is what we were trying to do.

And to make this actually feasible in practice you have to realize that Jay's Donut Shop is not unique.

Jay although not the most common name isn't even unique in the donut world and there's a lot of competitors.

So, the first thing I'm going to need is I'm going to need a universal unique identifier to represent Jay's Donut Shop.

Now if I go into an OS X machine and I create I use uuidgen I can get one of these.

And so, once I've done this once I now have an identifier that I'm going to use to represent my stores.

And the odds that anybody else could accidentally use this identifier to represent my store is very slim.

Now obviously somebody could maliciously copy my identifier but in general this is a unique way for me to see my stores.

To turn this into practice I'm going to have an application delegate that's going to go ahead and construct a uuid object from this string that I've precomputed and also going to store the fact that this is Jay's Donut Shop.

Uuids are great but it's also much easier to code if you have a human readable identifier, especially if you're going to deal with multiple beacons inside of one app.

And, of course, this is based around a location manager so you're going to have to create one of these and set yourself up.

Now when I'm ready to start monitoring for my stores I can implement a function that looks something like this, startMonitoringForStores.

And all I have to do is construct a CLBeaconRegion object, specify the proximity uuid that I've generated.

This is the one that all of my stores are going to advertise and then specify identifier.

This identifier is what uniquely identifies it to your instance of core location such that if you decide to change its parameters after the fact or uninstall it you can use that identifier to do so.

Lastly, startMonitoringForRegion.

This is the exact same region monitor in API that you're already familiar with and now it's been expanded to handle these BeaconRegion objects.

This means in turn that when you get an entry notification you handle it exactly like you would a geolocation update.

Specifically saying that hey, is the identifier of the region that I've entered the same as the one that I care about?

Okay, go ahead and tell the user that they are at Jay's Donut Shop.

This is a great first step at a product.

Now my friends can, that are trying this app can go to a store and get immediately notified that hey look you're inside of Jay's Donut Shop.

But one of my friends came back to me and said hey look, you've got that Jay's Donut Shop over at Valley Fair Mall and whenever I go inside there and I go buy some shoes the result is that my phone starts vibrating because I go by Jay's Donut Shop.

So this is relatively annoying.

The reality is that users don't necessarily care that they're inside of Jay's.

They're usually seeking to interact with your store.

And when they're ready to do that they're perfectly capable of pulling their phone out of their pocket and turning their display on and launching their application themselves.

So, but we can still speed the process up by letting you know when they've turned on their phone inside of a store.

And so to do that there's an added property that BeaconRegions support which is notifyEntryStateOnDisplay.

And now any time a user turns on their phone inside of my stores my application will get a launch event and I'll have the ability to respond to the user's interaction.

And, of course, we can disable the notifyOnEntry.

This is spurious wake that wasn't really relevant to the user.

There's no reason to know that we've walked by Jay's or even stepped into Jay's until I'm ready to interact with my phone.

And we're going to leave the notification on exit around in a second.

But now if I monitor for regions this way that my friend that's walking through Valley Fair doesn't have their phone vibrating in their pocket all the time, they can go get their shoes and then when they're ready for a donut they can now interact with my app.

The problem is that when they interact with their app in line they get that fantastic notification welcome to Jay's.

Here's all these cool things you can do.

They buy their donut, they sit back down at the table.

They're drinking their coffee, they pull out their phone to check their email; hey welcome to Jay's.

So, it's important to keep in mind that this will fire every time their display turns on if they're inside your store.

So, what you're going to want to do is if you haven't already presented a notification then go ahead and present a notification.

If you've previously notified them that hey, you're in Jay's you don't really need to have another notification pop up on their lock screen or worse over what application they're trying to use.

So, this is on you guys to figure out how to not to keep track of the fact that you're inside of a store.

And it I might be a good idea to then track when you leave the store so any notifications that are still lying around on the lock screen you can clear and similarly you can rearm yourself for the next time the user uses the phone inside of a different store.

So, that's a great first step, but the reality is that welcoming people to Jay's Donut Shop doesn't really buy them much.

What can you do with a warm welcome?

That's what my employees are for.

I pay them a lot of money to be very smiley and friendly to me.

So, wouldn't it better so let's come up with a use case around this.

So, one of the things that you can do on my website is you can order donuts online and you can have them ready for pickup at a store which means that you know you go home, you print off a receipt, you bring the receipt in the store and they bring you a box of donuts.

Wouldn't it be better if you could turn your iPhone into that receipt?

The reality is that we have had this technology for a while and anybody can do it.

What's going to make my application unique is that when I approach the cash register my phone is going to know that I'm at the cash register and it's going to present me a notification saying, hey now's a good time to pull out your receipt because your donuts are ready; you can pick them up.

To do this we need to know approximately how far we are from the cash register not just the fact that we're physically inside of Jay's Donut Shop.

So, to achieve this iBeacon supports a notion of ranging.

And so if we took that same Bluetooth little energy signal and if we kind of conceptualize it as a field where the closer you are to Jay's Donuts the stronger that signal's going to be and the further away you are the weaker its going to be, we can ascribe rough categories to that distance.

So, you're immediately on top of the beacon.

You're somewhat close by or really far away or we don't where the beacon is, probably because we've never seen it before or we can't see it right now.

So, with this rough notion of ranging we can actually achieve this notification that's specifically tied to a location inside of my store and not just the store more broadly.

So, going back to my region monitoring example when I know that my user's turned on their phone inside of the store, because again I'm not notifyingOnEntry when the display is on.

Now, whenever this happens I can start ranging for beacons in this region and so any beacon in the store that I can see after I start ranging I'll get an individual I'll get an update that coalesces all of them and tells me the approximate range to each of them.

So, locationManager didRangeBeacons In Region will have this array of beacons that I can see.

And as long as that beacon count is positive I can take the first object in that array, which is roughly equivalent to the closest beacon.

Now, you have to realize that this not 100 percent precise and so it might not actually be physically the closest, but it is the one that we're seeing and its roughly it's approximately the closest.

And more importantly in Jay's Donut Shop there's only one anyway.

So, if I check to see if that proximity is immediately in my vicinity then now's a good time to show the receipt notification.

And of course, if all the beacons drop down to zero that means that I've left the store and I can't see any beacons and so it's a good time to hide the receipt.

And similarly to before, we want to bookend this with clearing out notifications.

So, when we exit my store it's a good idea to stop ranging for beacons in the region, because you're not going to see any more if you're not inside that field and similarly hide the receipt if you haven't already.

So, this is a great way to do approximate ranging to things and know where you are and relative to a beacon.

So what beacons actually are is they support a number of properties.

The first is the proximity uuid.

This is the universal unique identifier that you've told us to monitor for.

And when we find the beacon that matches it, this is the beacon that we return to.

And every beacon that every beacon has one.

And when we get when we see one we have the approximate range to that beacon.

And this is one of four types the unknown, immediate, near or far.

And lastly there's these two other fields, a major and a minor number.

These are two 16 bit values that are completely customizable that you can program onto the beacon yourself.

What can you do with these?

Well, in Jay's Donut Shop I had this problem.

I had a friend that like really liked Jay's Donut Shop and he went to the shop multiple times a day.

And when he tried to use my pickup order system he went to one store in the morning and then his donuts were available at a different store in the afternoon.

But when he got to the store in the morning he got a notification.

It would be like hey your donuts are ready.

So, if we encoded the store number as the major identifier and we got, read that off the beacon as we arranged for it and we compared that to the receipt that I already knew where the store was which store was involved in the purchase, now I can notify the user only when they're at the right store.

They go to the wrong store.

I'm glad you like donuts, but they're not going to get the donuts they previously ordered they'll have to get some new donuts.

And so, this is just one example.

A common example is setting the major identifier to represent a particular store location and so you can monitor for a uuid of your stores that's universal across all of your stores.

But the major identifier is just tied to this one particular instance.

So what about the minor ID?

Forget the stores, what can we do with a minor ID?

Let's go back to the original donut shop example.

Welcome to Cupertino, try an apple fritter.

If each store which we're representing by a major identifier also advertised a particular donut, that it was its particular specialty, now without even bothering to hit the internet you could just look up for that donut on your database in your app and say hey look this number corresponds with apple fritter.

Tell the user that if you're in Cupertino you really should be trying an apple fritter.

And so this is just one example of how you could customize major and minor for your application.

Let's look at another example.

Let's look at something bigger than Jay's Donut Shop.

Let's take a department store.

Now you can monitor for all of your department stores and when you're inside of a department store you know which one you're at, but all of your department stores are pretty much uniform.

They all have the same departments.

What if each department had it's own beacon inside of it.

Again this are Bluetooth low energy devices so its will be possible to manufacture relatively cheap ones and we're intending to release a Bluetooth profile for those of you that are familiar with it that will allow other manufacturers to produce these.

But if you embedded one of these cheap devices inside of each department now when your user is inside the store and they're at the jewelry section and they pull up on their phone they could see a list like current sales or promotions on jewelry.

Or if they walk into the menswear section they could realize Father's Day is coming up in a week.

It might be a good time to buy dad a tie.

These are the types of specific things that you can do once you know more information about a particular beacon and how far you are to it.

You could have a museum where each painting was tagged with different beacon and you could pull it up in your catalog of paintings and know all of the information relative to that, maybe that section of the museum that you're in.

There's another example and that is keep in mind that these are small devices.

They're mobile.

You can put one in your pocket.

You can walk around with it.

You could also glue one onto the side of a bus.

Now if you did this and you encoded the major identifier as the route information now when you're seeing a bus and you're looking at your phone you could know exactly where this route takes you.

And, in fact, we already code this in human lands to integers anyway, because quite frankly bus numbers are sometimes easier to deal with than route names.

But there's an added problem with buses and trains and that sometimes a train might run express versus not.

And if it's going to run express it might only stop at a handful of stops.

So if I encoded the particular bus number on a minor identifier and my user was using my transportation app in a station and was ranging, when that bus pulls into the station they could immediately know hey this is the bus that's going to take me home or no actually this is going to skip my stop; I should wait for the next one.

This is some important information that you could this is just one example of information that you could encode that's contextually relevant to the user.

Now I mentioned that we're planning on allowing other people to manufacture beacons.

But for starters let's take something that you probably already have and turn it into a beacon.

Modern iOS devices that are capable of Bluetooth energy are in scanning for beacons can also themselves become beacons.

And so if you create a beacon region with the same proximity uuid major value and minor value that you'd like to scan for, then you can actually ask for a location to encode that information as peripheral data.

And you can then pass that on to a core Bluetooth peripheral manager that you've already instantiated inside your app and you can start advertising that data.

And of course this is calibratable and so you can specify exactly how loudly that beacon should advertise.

So, if you've got a small store you might not want to shout quite as loud, that way it doesn't blast out into the street, but maybe if you've got a bigger store you need a bigger field and this is tunable.

And there's going to be sample code online for a project called Air Locate.

It's both going to show you usage of our API in terms of using beacons for fencing and ranging but also turning a device into a beacon and letting you experience guiding you through the calibration process of exactly how to tune the advertisement suitably for your store.

So, tying beacons back into the CLRegion API.

Previously we had a CLRegionObject.

This is what all of the APIs could take in terms of a startingMonitoringForRegion for getting the current list of regions.

So, to expand this to BeaconRegions we subclassed CLRegion to support a CLBeaconRegion.

Now you might be aware that because the CLRegions were geared towards geospecific data they had a center on the earth and they had a radius.

This doesn't really make sense in the context of a beacon which could be glued to a bus or kept in your pocket or just is doesn't really have a center.

So, we refactored the code and we made available a new class, CLCircularRegion.

So, now in iOS 7 BeaconRegions and CircularRegions are your concrete classes and CLRegion is just this abstract class that the APIs support for monitoring.

And we're so we've deprecated CLRegion.

If you're targeting 6 and 7 and you need to be able to be backwards compatible go ahead and keep creating CLRegions.

They'll still work like CircularRegions did on iOS 6 and they'll be backwards compatible.

But if you're just targeting 7 and you're leveraging the beacon APIs obviously you need beacon and CircularRegions as your preferred target.

So, in summary please be aware of the multitasking changes with a little bit of a little simple check to your application, your UIApplication instance.

You can figure out whether or not these are exchangeable behavior for your application and you could tune their experience to make sure that they're aware of what limitations they've placed on you inside of the settings pane.

Similarly if you have a fitness application, please go ahead and defer location updates.

Honestly it's about an hour's worth of work to make your application defer updates available or support deferred location updates and 40 percent battery savings is kind of the upper bound of what you can achieve if you use this.

So, it would be really great to just take that little bit of effort to do it.

And lastly iBeacons are brand new.

We've just scratched the surface on sort of the things that you could even achieve with them.

And I'm sure that there's going to be many more use cases that you're going to surprise us with.

So, please go out and experiment.

[ Applause ]


So, if you need more information Paul Marcos is our Evangelist for our team, pmarcos@apple.com.

If he can't answer a question for some reason he can get in touch with one of us and he can he's a great frontline resource.

Documentation is always available online and, of course, you can go to the Apple Developer Forums.

What's New in Multitasking, already happened on Tuesday.

This talks about the high level system multitasking changes and it would be a really good idea to review that session if you haven't already, especially with regards to location.

And if you're going to be leveraging the advertisement feature of iBeacons then go ahead and check the Air Locate project and also review the core Bluetooth session.

MapKit was this morning and there's a bit more on it this afternoon and the app store guys are going to be talking about using region monitoring inside of the app store app tomorrow.

So, that might be a good idea to check out.

So, again thank you for coming and thank you for making fantastic applications.

[ Applause ]

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US