Core OS • iOS • 47:06
Find out how your app can use new functionality in Core Location to do automatic check-in or journal the user's location. Learn how location authorization is changing to give the user more precise control of what location services an App is authorized is use, and what this means for developers and users.
Speakers: Brad Jensen, Stephen Rhee
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript has potential transcription errors. We are working on an improved version.
[ Applause ]
Welcome to our session on "What's New in Core Location". My name is Stephen Rhee and I work on the Core Location framework. So Core Location is available on both iOS and OS X, but today the new features that we're going to be talking about today are specifically for iOS. Now some of you may be new to Core Location or even iOS in general.
This will not be a review of existing Core Location functionality. For that, we recommend that you go to our past WWDC presentations online or check out our great documentation also available online. Also, we'll be having a lab session this Thursday, so I recommend you all come out and join us there with any questions that you have for us; however, I think that today will still be equally applicable and interesting to those of you who are new to iOS and Core Location, to those who are seasoned app developers familiar with both iOS and Core Location.
So what's new in Core Location and iOS 8? Today we're going to be talking about location authorization, visit monitoring, and finally what's new is indoor positioning; however, we won't have time to talk about that in this session but directly following this session here in Marina, there'll be a dedicated session to indoor positioning, so I recommend you all stick around for that.
So before we go on, I'd like to start with a brief history of location on iOS. Location was first introduced in iOS 2 and then in iOS 3, we added the ability get heading updates. In iOS 4, with the introduction of multitasking, came a whole slew of new functionality for location, including continuous background location, which allows your app to get continuous location updates while in the background, and region monitoring, also known as geofencing, which allows your app to be launched and notified when the user enters or exits a predefined region, to significant location changes, which also allows your app to be launched and notified when the user's location has changed significantly.
In iOS 5, we introduced new APIs for geocoding, both forward and reverse. This allows you to take a position that is a latitude and longitude and convert it to an address or place mark and vice versa. In iOS 6, we introduced a power-efficient means of getting location updates, referred to as deferred location updates, in which locations will be batched up and delivered to your application at a app-specified time and/or distance interval.
And just last year in iOS 7, we introduced iBeacon technology, which has really been taking off. This allows you to determine proximity via ranging and region monitoring APIs, which brings us to iOS 8, which is what we're here to talk about today. As you can see, location functionality has been growing in iOS, as have the number of apps that you guys have been developing.
In fact, there are over 680,000 apps using location on iOS. These are all kinds of apps ranging from navigation to help users find their way home, to travel apps, to help users find interesting things to do around them, to fitness apps to allow users to track their exercise sessions, and shopping apps to help users find stores and deals around them, to social apps to allow users to interact with their friends, and even gaming apps to allow interesting uses of their location.
So what does location look like on the device today? There's a visual indication of location in use via the status bar location arrow icon. This can be solid, as we see here in the example of maps, which is displaying the user's current location. Generally, the solid arrow indicates that location or ranging, or significant location changes is in use.
Here, even on the home screen, if there's an application using location or significant location changes in the background, the solid arrow will remain lit. In addition to the solid arrow, we have the hollow arrow, which indicates that region monitoring is in use. Here, we see a traditional example of region monitoring, the Reminders app, which uses region monitoring to deliver reminders when the user has entered or exited a pre-defined location. And again on the home screen, if there are still apps using region monitoring in the background, the hollow arrow will remain in the status bar indicating that region monitoring is still in use.
Next, the user can control and get a finer picture of location usage via the Location Services settings. This is the Settings app under Privacy, Location Services. At the top we provide global control of location services. And down below, we provide individual per app control of location. In addition, per app, we provide an indication of location usage by that app. This can be indicated by a solid purple arrow indicating that location has recently been used, to a solid gray arrow indicating that location has been used within the last 24 hours, or a hollow purple arrow indicating that region monitoring is in use by the app.
So what does authorization look like today? Authorization is a single request that is prompted implicitly on first usage of location by your app. This is for all location functionality including location directly in the app, location from the background, location use via region monitoring, and significant location changes. The text is also customizable by the app. Here we see a "camera would like to use your current location" with a description of why camera uses location.
When location was first introduced, the request for the user's current location was pretty clear; however, with the advent of multitasking and all the powerful location functionality that we talked about was introduced allowing you to create very cool and powerful apps, we felt that the user could use more clarity of when location is being used and more importantly, we felt that your apps could benefit too.
We don't want the user to disable location, overall, either globally or for your app, disabling some of the cool functionality that you've developed using location. We want them to understand exactly how location is being used, so ultimately they can make better, more informed decisions and we believe that this is better for battery and better for privacy. So to that end, we're changing the way that location services works in iOS 8.
We started by looking at first at all the functionality that location services provides and categorized it into continuous updates, which includes location, background location, and ranging, and also location monitoring or events, which may launch the application to deliver callbacks. This includes region monitoring and significant location changes. And we broke it down into two authorization types, the first being Always. This is just like what location authorization provided in iOS 7.
It provided both access to continuous updates and location monitoring even when the app is in the background. But then we also introduced WhenInUse, which is only for continuous updates and it's only when the app is clearly in use by the user. So let's take a closer look at Background Location.
Starting with continuous background location, which is specified statically by the app either via the Capabilities tab in Xcode for background modes, location updates or via your app's information property list via the UIBackgroundMode key specifying a value of location. This, as before, must be started in the foreground, otherwise or if your app is using significant location changes. And this is available with WhenInUse location authorization because, now in iOS 8, we'll provide an indication in the status bar that your app is using location.
This is just like the status bar for navigation, when navigation is running in the background. Here, we'll indicate which app is using location and, if there are multiple, we'll indicate the number of apps using location, and the user can tap on the status bar to quickly return to the most recent app using location in the background.
One note is that if the application is authorized for Always location access, the status bar will not be presented because the user has granted access for that app to use location at any time, which is what is needed in order to access location anytime from the background. For example, when your app is running in the background due to Background App Refresh or due to region monitoring or due to significant location changes, this requires explicitly Always authorization.
So on the topic of multitasking, I'd like to clarify location behavior. When the user quits an app from the App switcher, this will immediately stop Continuous Background Location; however, this will not stop location monitoring such as significant location changes or region monitoring. This latter point is the behavior as of iOS 7.1.
And now in iOS 8, disabling Background App Refresh will no longer disable any location functionality because we believe with the introduction of the new location authorization types, the user is now in complete control of location usage. So how does this all look like to the user? Apps must now explicitly request authorization via new APIs. We'll get into the exact details of what this looks like in just a bit. Apps can request for either WhenInUse or for Always authorization.
Here, we see an example of the authorization dialogue presented to the user. For compass, it says Allow Compass to Access Your Location While You Use The App. And below, we see that customizable text that your app can provide indicating why it is that your app uses location. This text is now mandatory and no longer optional.
This dialogue will be presented only once to the user for either request to location access for WhenInUse or Always. And as we said, that text is customizable and is mandatory to provide. Quickly, we see an example of the Always authorization dialogue, where it states Allow Weather To Access Your Location Even When You Are Not Using The App. Again, the text description below describing why it is that the app would like to use the user's location.
So as we see, this Always authorization, which is what users got in iOS 7, is pretty powerful. Because of this, if Always authorization was granted by the user, the user will be asked to confirm a few days later and only if their Always authorization was exercised, that is, the app did use location in the background perhaps due to region monitoring or significant location changes.
Here we see an example of what that dialogue looks like, where it says, "Weather Has Been Using Your Location In The Background. Do You Want To Continue Allowing This?" And again, we see that the text is customizable. It's the same usage description provided in the original request for location authorization.
So now let's take a look at the new Location Services settings pane. Apps can support WhenInUse and/or Always authorization types and this is specified statically by the app. Again, we'll see the details of exactly how you can do this in just a bit. And now in the Settings pane for each app next to the Location Usage indication, it will have the text describing exactly what that app is authorized for. In addition, the user can tap on the app to see what authorization and status types are supported by that app with a text description below indicating, describing that current selection. Here we see an example for WhenInUse app.
And quickly, another example for an app that supports Always. Note that in this pane, we don't show the app description of why that app would like to use the location in the current seed; however, you, as developers, should prepare for this because we believe that this may present another great opportunity to inform the user why it is that your app uses location.
Now also new in iOS 8, when the user goes to the Settings apps for your apps specifically, a link to Privacy will be included, which also includes a link to Location Services, if applicable. Here we see an example, Fitness app. The app Settings pane, we see the Privacy. The user can tap on that and get to the Location Services pane specifically for its app right there and change the authorization status immediately.
Now this is going to be even more powerful for you as app developers because now in iOS 8, your app has the ability to programmatically jump directly to your app Settings pane. This is done with the existing openURL method on UIApplication providing the new constant in iOS 8, UIApplicationOpen SettingsURLString. We'll see exactly how useful this can be later in an example.
So you all are probably wondering, that's looks great and well, so what is it that I as a developer have to do? Well, starting with the actual interface changes, there are only three changes that you need to be aware of, the relevant Info.plist keys that we talked about, the authorization status enum values, and finally the new authorization request APIs. So let's dive right in, first starting with the Info.plist keys.
Previously we had the NSLocationUsageDescription, which was optional and allowed you to customize the text displayed to the user why it is that your app uses location. This is now deprecated and replaced by two new keys, NSLocationA lwaysUsageDescription and NSLocationWhen InUseUsageDescription. Note again that's specifying one or both of these is now mandatory, depending on which authorization type it is that your application supports. The value is the string describing to the user exactly why it is that your app uses location. We believe that this is really going to help users understand how it is that your app uses location.
Moving on to the CLAuthorizationStatus enum. Previously there were a number of values, one of which was kCLAuthorization StatusAuthorized. Now, this is deprecated and replaced by two new values, AuthorizedAlways and AuthorizedWhenInUse, depending on which authorization was requested by your app and which authorization was granted by the user. Accessing authorization status for your app has not changed.
This can be done either via the class method on CLLocationManager AuthorizationStatus or via the delegate callback via ChangeAuthorizationStatus on the CLManager delegate; however, requesting authorization has changed, which brings us to the third interface change, Request Authorization APIs. Requesting authorization is now explicit either for Always or for WhenInUse.
Your app can make calls to these requests APIs repeatedly; however, it will only prompt to the user the first time and not per type. So if you support both authorization types, you'll need to carefully consider which you want to request in your app. We'll go further on this in an example in just a bit.
So putting it all together, there are three simple steps to adopting the new authorization in iOS 8. First, you want to decide which authorization it is that your app supports by asking yourself these two questions. What location functionality does your app use and is that a mandatory functionality or a nice-to-have functionality for your app. Second, you want to explain it to your user exactly how your app uses location.
And third, you want to make the right call to request authorization and you want to do it when needed. For example, when your app first launches, don't make the request to access location because the user won't understand why it is that your app is requesting location authorization and they may be inclined to just deny that.
Instead, do it in response to explicit user action so that they have context and in addition to the usage description string that you provide why your app uses location, the user can then make an informed choice of whether to allow or disallow location access to the app. Let's go through some examples.
First, let's say you've developed this great fitness app that tracks the user's runs. You want to start by first determining how it is that location is used. Obviously, this app is going to use location. In addition, it's going to use background location in order that the user may Home-out of your app and switch to the music app and play their favorite tunes.
So background location can be enabled via Xcode in the Capabilities tab, making sure that background modes is on and that location updates is selected. Alternatively, you can edit your information property list for you app specifying the UIBackgroundModes key with the value of location. Second step is to add the appropriate key to your app's information property list. Here in Xcode, we'll go to the Information Property List Editor and add a new key for NSLocationWhen InUseUsageDescription providing the description to the user that your location is used to track your run.
And third, the final step is to make the appropriate API call to request authorization and do it when needed. So here, after creating your locationManager setting to delegate and right before making the call to startUpdatingLocation, all you need to do is make the call to requestWhen InUseAuthorization. Pretty simple, right? Let's move on to another example.
Let's say you've created this great WelcomeHome app that's going to automatically turn on the lights and maybe even unlock the front door when the user has arrived at home. Again, you'll want to start by determining how location is being used by your app. In this case, it's using region monitoring to detect when the user has arrived at home.
Next, you'll need to add the appropriate usage description key to your app's information property list. Again, you'll go to the information property list editor in Xcode and this time add a key for NSLocationAlways UsageDescription providing a description to the user here in this example. Here location is used to determine when you arrive home.
And finally, you'll want to make the appropriate call to request authorization and again, do it as needed. In this case, right before the call to start monitoring for region, you'll want to add the call to requestAlwaysAuthorization. Again, pretty straightforward. How about if your app actually supports both authorization types. Let's say you've developed this great app for an amusement park. In the general use case, it'll show the app's current location in the AmusementPark map but let's say you've developed this cool feature that will additionally deliver cool information about nearby attractions to the user.
And in this case, you'll want to determine exactly how it is that your app is using location. Obviously, for the general use case displaying the user's location on the map, you're using location. But for that cool feature that tells them about cool attractions nearby, you're going to be using region monitoring.
So again, we follow the same steps. First, we're going to add the appropriate usage description keys to the app's information property list again by going to the property list editor in Xcode. We'll first start by adding a key for NSLocationWhen InUseUsageDescription specifying that your current location may be shown on the map. In addition to that, because your app also supports Always authorization, you'll add a key to NSLocation AlwaysUsageDescription, again providing a description to why it is that your app uses location. Here, this app will use your location information to identify nearby attractions.
So in your app's information property list, you'll actually have both of these usage description keys because your app supports both of these authorization types. And finally, you'll want to make the corresponding authorization request API calls. Again, you'll want to do this when needed. For example, in the map view that displays the AmusementPark map, you'll want to right before startUpdatingLocation, you'll make the call to requestWhenInUseAuthorization.
And for that power user use case, still in response to user action, perhaps the user has now enabled the feature that enables the automatic attraction info mode that delivers information about ride times for the nearby attractions or store sales or restaurant specials, but in this case, you may want to check your app's authorization status first because if it's denied or when in use, you'll need to tell the user that they need to authorize your app for Always authorization.
And in this case, you may want to present an alert indicating that and offer to take them directly to the Settings app for your app's settings pane using that mentioned openUrl method with the new UIApplicationOpen SettingsURLString. And then finally, right before you start to call to start monitoring for region, you'll make the call the requestAlwaysAuthorization.
So some additional details, what if you want to support both iOS 7 and iOS 8 with your app. Well there are three things that you want to consider, the lineup with the three interface changes we discussed earlier. First, you'll want to continue to provide the deprecated NSLocationUsageDescription string if you were doing so before. In addition, to specify one or both of the new Always usage description or WhenInUse usage description keys.
Next, you'll want to guard the request authorization API call with respondsToSelector so that your app will still work on iOS 7. Here's a quick example of exactly how to do that. And third, you'll want to continue to use the deprecated kCLAuthorizationStatusAuthorize value in addition to the new authorize Always and authorize WhenInUse values.
So I bet you're wondering, what about legacy app support, what if you don't update your app but your user upgrades his system to iOS 8, what's going to happen? Well, your app will still continue to work but it will use Always authorization. So you don't want to rely on this because when the user uses your app and uses location for the first time, it's going to pop that dialogue asking for location access Always even if your app only uses WhenInUse location functionality, such as location in the app or background location or ranging.
So your user may at that point decide to disallow location usage. So you don't want this to happen. You want to update your app now and you saw exactly how simple it is to do so. So what about updating your app? You can change the supported authorization types anytime you update your app and so when your user updates the version of the app, the version of your app on his phone or device, it will preserve the user's authorization if still supported.
Otherwise, it will go from Always to WhenInUse. For example, if your app no longer supports Always authorization but now supports WhenInUse and it'll go from WhenInUse to prompt again. For example, again if your app no longer supports WhenInUse in this case and may now support Always authorization. But again, don't wait to adopt because if the user denies location access to your app, it will stay denied even if you subsequently change your app to support the WhenInUse authorization type.
So what about other frameworks where location is used? Let's go back to the example WelcomeHome app. Let's say that you don't want your app to automatically turn on the lights or even more dangerously unlock the front door automatically. Instead, all you want to do is notify the user and let them decide to choose to take action on that notification.
In this case, your app actually doesn't need to be launched, just a notification needs to be provided and now in iOS 8, we've added region-based triggering to UILocalNotification via the specification of the CLRegion property on the UILocalNotification. In this case, your app doesn't need Always authorization because your app will not be launched in response to region monitoring. Instead, the system will provide the notification that you specified to be provided to the user on behalf and only when the user decides to respond to that notification and launch your app will your app actually be in use.
So usage of this API requires either authorization Always or WhenInUse but only needs your app to be supported for WhenInUse authorization. And the steps to use this API are the same as any other location functionality. You'll want to specify the desired usage description key in your Info.plist with the text string describing how it is your app uses location and call the corresponding authorization request API, as needed.
What if you use MKMapView on your app to display a map view with the user's current location via the showsUserLocation property on the MKMapView class. Again, this requires either authorization for your app but only needs your app to be authorized for WhenInUse authorization. And the same steps as before, you need to specify which authorization your app supports in your app's information property list and make the corresponding API call to request authorization when needed. One last one I'd like to talk about, web views. To allow web content that uses HTML5 geolocation to access the user's current location, this one also requires either authorization but again only needs the WhenInUse authorization.
Again, you'll specify in your app's information property list the usage description keys relevant with a text description why it is that your app would like to use the user's location; however, in this case, the authorization request will be made automatically for WhenInUse on your behalf because you may not know when the user navigates to a web page that uses geolocation; however, if your app uses Always authorization, you'll want to make that authorization request in advance, if so desired.
So a quick recap, get ready for the location authorization changes that are coming in iOS 8 by following these three simple steps. First, think about how your app uses location. Second, explain it your users. And third and finally, make the call to request authorization. Don't wait. Do it today. And then if you have any questions, on Thursday, you can come to us in our lab session here this week at WWDC with any issues or questions that you encounter. Next, I'd like to introduce Brad, who's here to talk about Visit Monitoring.
Thanks Stephen. I'm Brad Jensen. I'm a Core Location engineer and I'm excited to introduce to you Visit Monitoring. But first, I want to write an app with you. See, Apple engineers aren't allowed to publish apps and I really want a journaling app, so you're going to have to help me out with this.
Journaling apps are really interesting to me but more importantly, they're a great example of Visit Monitoring. It's a great type of app that makes use of this new technology. So, what constitutes a journaling app? Well, first and foremost, it's got to provide the user a list of locations of where they've been during their day.
But more importantly, that list of locations needs to be relevant to them. If we list every time they stopped at a interaction or a stop sign, then they're not going to find that list especially useful. Finally, we want to make sure that our journaling app can last all day.
If it's going to drain the user's battery in two to three hours, it's not going to be very useful. So, let's take a look at the different Core Location APIs that exist today and we'll see why none of them really work well for journaling apps. If you're working on a check-in app, you might find this awfully familiar.
First up is the standard location service. This is where we provide your app with periodic location updates as they become available. Naturally, if we're going to be providing updates to your app, this requires the phone to be awake and even more importantly, the radios have to stay awake. We have to periodically scan for Wi-Fi networks, for cell towers or GPS. Now, all of this is fairly expensive and that means that the app is going to be consuming a lot of power.
In addition, the app is going to receive a lot of irrelevant data. You're going to have to take the stream of locations and try and make sense of it, try and identify those locations that are probably significant to the user. So this isn't really a good fit for a journaling app, but if we were instead writing a navigation app, this would make a lot of sense. You need the most up-to-date information available in order to tell the user when to make their next move.
Before we totally throw out standard location service for journaling apps, there are a couple of improvements we might consider. A while ago we introduced the automatic pause feature. This allows Core Location to save power by pausing location updates once it's determined that the device probably isn't in motion anymore. This is really exciting because it means, well, we get to save power. The device gets to keep journaling longer. Unfortunately, once the user starts moving again, your app will have to resume those location updates.
And so we won't actually help or this won't actually save standard location service in terms of writing journaling apps. If we were writing that navigation app, however, this would be a huge win. Once the user stops at a gas station, automatic pause will save their phone's battery. Another option we might consider is deferred location updates. This one is really interesting as well. It allows Core Location to save power by waking up your app less.
App wake-ups cost power and so fewer app launches means more power saved. Unfortunately, generating locations is still quite expensive and so even though we're saving power by not launching your app every time there's new data, we're still generating all those locations and not especially great. So, deferred location updates aren't exactly what we want; however, if we were writing a fitness app, they would be great. If you're writing a run tracker app, you don't necessarily need the latest location in the moment that's available. It might be okay to receive it every mile or every 15 minutes or so.
All right, what else do we have for us? Well, there's the standard or the significant location change API. This one is a lot more power efficient than continuous location updates, but there's a cost to this. Instead of getting all of the data, you get very coarse tracks of where the user went. Specifically, you only get location updates every few hundred meters the device moves. This is going to make it incredibly difficult for us to identify places that the user stopped at since when the user stops, we stop giving updates to your app.
If we were writing a different app, for example one that showed the user the path they took home, maybe identifies the freeways they drove on, then significant location changes would make a lot of sense. But we're working on a journaling app today, so we're going to have to keep looking.
Our last option is region monitoring. Region monitoring is really cool because it's highly power efficient. Region monitoring can continue while the phone is asleep and your app only receives information that is directly relevant to it. Unfortunately, you have to specify which locations are interesting to your app and that won't exactly work for our use case because we want to know about all of the interesting locations the user might go to and there are far too many interesting places to monitor for them all.
So, that's all that Core Location has today. Do we give up, I have to give up on my dream app? Not yet. There's another one. We're introducing today Visit Monitoring. What makes Visit Monitoring different from the other Core Location APIs is that it monitors for destinations. So instead of giving you information about how the user got from A to B, it gives you information about A and B. It will launch your app when it detects that the user has departed from a location or arrived at a new one and so naturally this will require Always authorization.
Visit Monitoring is incredibly power efficient. We employ all sorts of neat tricks behind the scenes to ensure this. For example, while the device is asleep, it periodically performs Wi-Fi scans. If Visit Monitoring is active, we're able to harvest all of those scans that would otherwise have not generated locations and use them to enhance our visit detection.
Visit Monitoring is also opportunistic. So, if your app is using Visit Monitoring and the user pulls out apps and starts navigating, all of the locations that maps requests are fed into the visit detection algorithm and so your app benefits from other apps' use of location. Finally, it utilizes information from across the entire system.
For example, suppose the user arrives home and plugs in their phone to start charging. It's much more likely that the user would consider this location where they started charging to be an important part of their day and so we'll use that as a hint that the user has just arrived somewhere. When we see hints, we'll trigger arrival events much more readily.
Finally, I'd like to point out that Visit Monitoring is not tied to landmarks. I mean, when you receive information about a location, it's not necessarily an intrinsically interesting location, it's just a location which is interesting because the user has spent time there or we've seen some hints which indicate the user might think it's interesting. So, let's look at what a visit actually is. Suppose your user has turned on Visit Monitoring through your app and they decide they want to go get a cup of coffee, so they start walking from their home to the coffee shop.
At some point, Core Location will get its first location of the user at the coffee shop. I don't know about you but I can't see the future and so Core Location is going to have to wait a little while before it can say for sure whether the user is passing by the coffee shop or whether they're there to say for some time.
After we get a little bit more data, it becomes clear that yes, the user intends to stay at the coffee for a while, maybe it's time to notify some apps. At this point, Core Location will launch your app and provide it some information about the arrival. Most importantly, however, it will do its best to estimate the true arrival time of the user at the location.
Departures work similarly. After some amount of time, we'll get our last location of the user at the coffee shop, but Core Location will wait until it gets a little bit more data until it's sure that the user has left. At that point, we will wake your app again and we'll provide a departure notification, doing our best to estimate the true time when the user left the location.
So, let's take a look at the API. We've added two new methods to the locationManager, specifically startMonitoringVisits and stopMonitoringVisits. When we have information to deliver to your app, we'll do it through the new delegate method locationManagerdidVisit. Some of you may have noticed there's a new class in that method's signature, specifically CLVisit, so let's take a look at that.
CLVisit is a fairly simple class. It's got four properties. The first two are arrivalDate and departureDate; these describe when the user arrived and departed, respectively. The coordinate, which represents the place the user was visiting, and horizontal accuracy, which is an estimate of the error on the location, on the coordinate.
A few things you might want to know about Visit Monitoring. The values of horizontal accuracy and coordinate may differ between an arrival event and a departure event. This shouldn't be too surprising. These are estimates based on the data we have seen and as we get more data, we'll be able to produce better estimates.
You should also note that horizontal accuracy should be no worse than the horizontal accuracy on a Wi-Fi-based position. So, if you find Wi-Fi-based positions are suitable for your app, Visit Monitoring will probably produce things of equal value. Naturally, since this is a background monitoring service, we'll launch your app even if it's been quit, as Stephen mentioned. In addition, if the phone is rebooted or your app crashes, we'll still launch it and provide it with this information.
You should also know that there are cases in which Visit Monitoring might detect multiple visit events at the same time and deliver them to your app in a single launch. So, when you receive visits, you should be prepared to handle multiple. You may have noticed that CLVisit doesn't have a isArrival or isDeparture property, so let's take a look at how you can determine whether a visit represents an arrival event or departure event.
The secret is to look at the arrival date and departure date properties. On an arrival notification, the arrival date will unsurprisingly be our best estimate of when the user arrived. The departure date, however, will be NSDate distantFuture. On a departure notification, the departure date will be our best estimate. The arrival date, I'd like to point out, could be distant past. This happens if your app wasn't authorized for the arrival moment.
So, how do we check if a CLVisit represents an arrival or a departure? You simply compare the departure date to distant future. Now, let's get back to that app. There should be four steps to implementing it. First, we need to adopt the new authorization model that Stephen described. After that, we need to create our locationManager, write our start and stop methods, and finally handle the visits that are delivered by Core Location.
Adopting the new authorization isn't too difficult. The hardest part is coming up with a great way to describe to your users how you intend to use their location. For this example, journaling app, we might say, this app needs your location to automatically detect the places you visit during your day.
After that, we create our locationManager. I went ahead and did that in the application delegate because it provides a great main thread context for us to allocate it in. The start and stop methods are fairly simple. The only catch is you have to remember to requestAlwaysAuthorization. And the stop is even easier: you just call stopMonitoringVisits. Finally, the delegate, this is where you take over.
Please keep in mind that background execution time is limited and, as I mentioned, you may receive multiple visits. So you shouldn't kick off some long-running, computationally-expensive processing task here. For a simple journaling app, it might be best to just record this visit in a database and then save it for later when the user actually launches your app.
If you're writing a check-in app, now might be a good time to take a look at the location, see if it's accurate enough for you to actually determine if the user is at a specific restaurant, for example, and then maybe fire off a UILocalNotification saying would you like to check in.
Before I give the stage back to Stephen, I'd like to give you some advice from the Core Location team about Visit Monitoring. Visit Monitoring is not a replacement for region monitoring. If you're currently using region monitoring to receive useful information about the user arriving at or departing from specific locations, you should continue to do so.
Region monitoring is more power efficient and will give you more timely information about those events. In addition, Visit Monitoring is not a replacement for significant location changes. They provide you very different information. Significant location changes is about the path the user too, whereas Visit Monitoring is about the destinations.
So, what do you do when you encounter new technology, you should try it out and evaluate it for your use case. See if Visit Monitoring covers something that your app needs. Then, on Thursday, we're hosting a lab. You should come to our lab session, bring any questions you might have, any problems you might have encountered, and we'll do our best to help you get your app up and running.
Finally, please respect your users' privacy. This is an incredible technology that will give your app a new level of location awareness but you should try to respect your users' privacy. Just because you can obtain this data, doesn't mean you necessarily should. If you have any questions, there's going to be a session about security and privacy later this week. I highly recommend you attend it. With that, I'd like to invite Stephen back up onto the stage to tell you about what's next.
Thank you, Brad. So what else is new in Core Location on iOS 8? Well there was that third bullet point we talked about, Indoor Positioning. Unfortunately, we don't have enough time to cover that in this session. In summary, we talked about location authorization and changes and recall that there are just three steps that you need to follow to adopt the changes in iOS 8.
First, you want to think about how your app uses location. Second, you want to explain it to your users. And third, you want to make the call to request authorization. And you should try this out today because come Thursday, you come back to us with any questions or issues that you've encountered in our lab session.
We also talked about Visit Monitoring. Take the opportunity to assess your apps' needs for location and see if this Visit Monitoring is cool technology is something that your app can take advantage of, but again remember, as Brad mentioned, to respect your users' privacy. And also on this one, give it a try, see what you can do, and then come back to us on Thursday with sample code or any issues or questions that you have regarding this new API.
For more information, check out our great documentation online. We have the Core Location Framework Reference, which is updated with everything that we've talked about today. We also have a Location and Maps Programming Guide, which is always being updated with new and useful information and, as always, visit the Apple Developer Forums.
For related sessions, we have a number that we highly recommend. The first on the Modern WebKit API, unfortunately, is at the same time as this session, so thank you for joining us, but for more information about web views, go check out the videos online afterwards. Also, as we mentioned, directly following this session, "Taking Core Location Indoors" for more on what's new in Core Location.
Also tomorrow, I highly recommend part 2 of "Writing Energy-Efficient Code", which will cover some good practices when using location in addition to other technology in your apps. Also tomorrow, "What's New In iOS Notifications" for more on the region-based UILocationNotifications and more. And on Thursday, visit the User Privacy in iOS and OS X for more details on location authorization and privacy and other privacy-related topics on both iOS and OS X.