LSDemo App
In Standard Location Provider II, we finished implementing the StandardLocationProvider. Now let's hook it back into the LSDemo app so we can exercise our prototype code.
We want the prototype to execute as though it were running inside a real iPhone app. Recall that after an app's UIViewController loads its associated views into memory, the viewDidLoad method is invoked to allow for additional initialization steps. This is where we will instantiate our prototype.
Open the LSDemo view controller header file (ViewController.h) and declare the locationProvider field:
(Again, it is marked @private because we do not need to expose the internals of the class.) Now open up the corresponding implementation file (ViewController.m) and instantiate the locationProvider:#import "StandardLocationProvider.h"@interface ViewController : UIViewController{@privateStandardLocationProvider *locationProvider;}@end
Finally, remember to relinquish the locationProvider reference in the viewDidUnload method:- (void)viewDidLoad{[super viewDidLoad];// Do any additional setup after loading the view.locationProvider = [[StandardLocationProvider alloc] init];}
At this point, everything is hooked up. Build (but don't yet launch) the sandbox app to make sure there are no errors.- (void)viewDidUnload{[super viewDidUnload];// Release any retained subviews of the main view.// e.g. self.myOutlet = nil;locationProvider = nil;}
iOS Location Services Alert Popup
The first time an iPhone app requests location services from iOS, an alert popup should appear asking the user to allow the service. As the CLLocationManager documentation explains:
During its initial uses by an application, the Core Location framework prompts the user to confirm that using the location service is acceptable.Let's verify. Go ahead and start the LSDemo app. The following alert popup should appear:
Core Location Errors
What happens if we click "Don't Allow" instead? When the user refuses an app access to location services, we expect the app to be notified via its CLLocationManagerDelegate, specifically the locationManager:didFailWithError: method. As the documentation explains:
If the user denies your application’s use of the location service, this method reports a kCLErrorDenied error.Let's verify. Click the "Don't Allow" button to refuse our prototype access to location services. The popup should go away, and something like the following should be logged to the console:
2011-11-01 10:58:52.172 LSDemo[276:f803] error=Error Domain=kCLErrorDomain Code=1 "The operation couldn’t be completed. (kCLErrorDomain error 1.)"An error was generated, as we expected. But is it the right error?
Let's take a closer look. From the documentation, we know the error sent back is an instance of NSError. The key properties of this class are its domain and a domain-specific error code. Looking at the error message above, we can deduce the following:
- domain = kCLErrorDomain
- code = 1
Yay! The error generated by clicking "Don't Allow" is consistent with expectations.
Now quit the simulator and try again. All subsequent attempts to run the sandbox app will result in this error. What's more, the popup has gone too. How do we fix this?