A popular method used from the CLLocationManagerDelegate protocol is – (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation which allows your app to receive updates when any location changes are detected. The new location details were stored in the newLocation which is a CLLocation.
When iOS 6 launched, that method was deprecated with a suggestion to use a newer version called – (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations or in short locationManager:didUpdateLocations:.
This quick tutorial has been created to explain how to handle a deprecated method, what should be done about it and where you can find out more details about the changes. If you want to know how to use the newer locationManager:didUpdateLocations: method then take a look at the didUpdateLocations tutorial that explains how to work with the NSArray provided by that method.
When Methods are Deprecated
When iOS is updated (which is regularly), Apple finds new and more efficient ways to provide methods through the API. When this happens, a method can be marked as deprecated with a hint of what to use in its place. In the case of CLLocationManagerDelegate, you can see it recommends a different method within the documentation (image above). Although you can still use deprecated methods in your code, even on iOS versions where a method has been deprecated, Apple at some point in the future might delete the method when iOS gets updated. At that point, you would need to modify your code, submit to the Apple store and go through the approval process.
How to handle Deprecated Methods
Methods that have been deprecated continue to work on newer iOS versions. Apple tends to keep them active for a few more version at which point, they then get deleted from the class or protocol. Rather than leaving your code till the 11th hour to be updated and resubmitted to Apple, you can make preparations now ahead of these changes.
In todays example, we are looking at the locationManager:didUpdateToLocation:fromLocation: method and how we can get both the older deprecated method and the newer method working from the same code.
We’ll carry on from our last tutorial where we had this code:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *newLocation = [locations lastObject];
CLLocation *oldLocation = [locations objectAtIndex:locations.count-1];
NSLog(@"didUpdateToLocation %@ from %@", newLocation, oldLocation);
MKCoordinateRegion userLocation = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 1500.0, 1500.0);
[regionsMapView setRegion:userLocation animated:YES];
}
To make this compatible with iOS 5 what we can do is add the old method – (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation in to the code and within that method, call the newer version of the method as follows:
– (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
The code would now look like this:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *newLocation = [locations lastObject];
CLLocation *oldLocation;
if (locations.count >= 2) {
oldLocation = [locations objectAtIndex:locations.count-1];
} else {
oldLocation = nil;
}
NSLog(@"didUpdateToLocation %@ from %@", newLocation, oldLocation);
MKCoordinateRegion userLocation = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 1500.0, 1500.0);
[regionsMapView setRegion:userLocation animated:YES];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[self locationManager:locationManager didUpdateLocations:[[NSArray alloc] initWithObjects:newLocation, nil]];
}
If iOS 5 is used, the newer method isn’t used and it just looked at as a custom method as iOS 5 doesn’t know what locationManager:didUpdateLocations: actually is. The older method simply alloc/inits a new NSArray called currentLocation and initWithObjects:newLocation is used to get the newLocation. The NSArray is then passed as a message to the locationManager newer method and acted on accordingly.
So in summary. If iOS 5 is on the device, the older locationManager:didUpdateToLocation:fromLocation: tells the delegate a new location is available. This takes the CLLocation, adds it to an NSArray which is then passed to the newer method which will be unknown to the operating system on the device.
If iOS 6 is used, we learn from the CLLocationManagerDelegate header (command click on the method to access this) in the notes that if both the newer and older methods are within the code then iOS uses the new method to let the delegate know there is an update.
Note that I added a simple count on the 4th line. This checks to see if there is more than 1 object in the locations NSArray. The reason for this is that on line 5, we are pulling the oldLocation out of the NSArray (if available). If there is only 1 object in locations then the app would crash when objectAtIndex:locations.count-1 is requested.
Although this quick tutorial provides one way of working with a deprecated method, there will be other ways out there. Also, look at the documentation and look at the class header files for the method because Apple has added a lot of information in there that might help you choose how to solve the task at hand.
Leave a Reply
You must be logged in to post a comment.