My primary objective at WWDC this year was to find answers to Core Location questions I had and develop some intuition about how the framework works underneath the hood. Armed with some questions and a small sample app illustrating some of the bugs I found, I set out for the one Core Location lab being run during the week. These "office hour" style labs offer developers an opportunity to talk directly with the Apple engineers who work on these frameworks, and after getting paired up with one of the more senior Core Location guys, I was blown away by how valuable these sessions can be. I was able to resolve several issues and had a bunch of questions answered while also picking up a few tips and tricks to use in future apps. The amount of knowledge and insight shared during my relatively short session was invaluable.
While I can't share everything I learned in the lab due to the NDA covering iOS 6 updates and features, I did collect non- iOS 6 specific concepts which I can share with you. Much of the information isn't documented even though it helps paint a fuller picture of how Core Location works. During my time in the lab, two things became clear: quality of the location services can be significantly impacted by variations in environment and hardware and that Apple engineers are still actively iterating and improving Core Location. I didn't get a straight answer as to why they are reluctant to publicly share or document some of this information, but I would not be surprised if these types of things were a factor.
Finally, this information was collected from some notes scribbled on paper during my lab session and a brain dump I did into nvAlt immediately following the meeting to get whatever didn't make it on the page. I am reasonably confident that what I captured in my notes is legit and valid information, but it is entirely likely that I misheard, misinterpreted, or misunderstood something. Caveat Emptor.
Region Monitoring Information:
The minimum region radius size is 100m. Core Location will allow you to set a radius value smaller than 100m for a CLRegion, but internally the framework will treat the region as if its radius was 100m.
The maximum number of regions that can be monitored at one time is 20. This is not documented anywhere, but if you try to register for more than 20 regions, you will get an error indicating that you can't add any more regions. One technique that is used to get around this cap is to load and unload regions based on your current location and using significant location change notifications to evaluate when old regions need to be removed and updated with regions closer to the user's current location. Keep in mind that adding and removing regions does take some power, so it is something that you want to do judiciously.
Regions fall into three categories. Depending on what category the registered region falls into affects the time it takes for Core Location to trigger the delegate callbacks.
- Fine Region (0 - 150m)
- With the floor of 100m this category's range is effectively 100-150m.
- For regions this size performance is heavily dependent on the location-related hardware in the devices. The iPhone 4S, unsurprisingly, has the best hardware. Some iPads and all iPod Touches don't have cellular radios. All these types of scenarios should be considered during development.
- The amount of time that it takes Core Location to detect and call the appropriate delegate method is roughly 2-3 minutes on average after the region boundary has been crossed.
- Some developers have figured out independently that smaller regions would see quicker callbacks and would cluster smaller regions to cover one large area to improve region crossing notifications. This was frowned upon by the Apple engineer as this type of solution uses more resources/power than monitoring just the single large region, but it is a viable alternative if you need the quickest possible updates. Apple is aware of this, and they are continually trying to minimize the time that elapses until Core Location invokes the delegate methods.
- "Normal" Region (150m - 7km)
- Core Location can take as long as 15 minutes to invoke the delegate methods, but it is usually less.
- Response time improves significantly with increased user interaction with the device. Core Location tries to minimize power consumption, so it doesn't accelerate battery drain and tries to piggyback on other activities to check location. A device that is actively being used to browse the web or send text messages is more likely to have Core Location checking for updates than a device that is idle in standby mode.
- "Huge" Region (7km+)
- This was referred to as the "1/3 of the earth" region. Outside of its mention and confirmation that category of region exists, not much else was said about it.
- Fine Region (0 - 150m)
Regions are not registered for instantaneously. If you register for a region and then immediately enter/exit the region, then it won't get registered properly. The recommended suggested wait time was 10s which is helpful to know when testing.
Bugs prevented the start/stop watching region callbacks from being invoked in iOS 5. The callbacks do not work properly in the simulator and only work correctly on some hardware devices. This appears to be fixed in iOS 6.
Other Core Location Tidbits
Significant location change (SLC) updates will not fire unless 5 minutes elapsed and a change of 500m occurred since the last update.
If you stop and then start registering for SLC notifications, there are no guarantees that it will fire immediately. Apparently enough people thought this worked and/or tried this that Apple changed how Core Location behaves and now a cached value (if Core Location has one) will be returned on the subsequent firing.
You can tell the source of your location information by observing the blue location dot used by MapKit. A pulsing dot means GPS (example) and a static dot means cell/wifi (example). This is not documented anywhere officially and apparently a lot of Apple engineers don't recognize/notice the difference.
Core Location quality/performance varies substantially based on where you are. In a high density area like a city, the device will pull less data and use less resources than if you're in a sparsely populated area.
Core Location piggy backs on other user interactions to do most of its updating. The more opportunities it has to check / update location, the better the response time.
The mocked location data that is provided to the simulator always appears to be coming from GPS. You can't simulate the behavior that the cellular or wifi sources provide or simulate what happens when the GPS source is sketchy. In prior iOS releases, region monitoring relied heavily (exclusively?) on the location data provided by cell towers to operate, but improvements to both the algorithms and simulator should mitigate any of these issues.