One of the great features in the iPhone is the ability to get your location, which is available on all of the versions with the 1st edition relying on cell tower triangulation, the rest using built in GPS. As a developer, I can think of endless possibilities for using this information, but the first step is getting a hold of the information. This tutorial is going to cover how to get location data using the iPhone SDK.
The goal for this tutorial is to build the super simple application, Where Am I? This application does one thing, it will tell you your current location and update itself when you move. There is much more you can do with this API, this example just shows the basics. You can see the interface with the location information below.
Ok, let's get down to it. The interface contains five UILabel controls. Pretty easy to put together and the important ones are for outputting the latitude and longitude. Just drop the labels down. We also need to update our view controller to have a couple IBOutlet variables for our labels. With the variables added go ahead and hook the labels to the IBOutlet in Interface Builder, if you need help with this check out our intro to Interface Builder. The updated view controller header file is below.
@interface WhereAmIViewController : UIViewController {
IBOutlet UILabel *latLabel;
IBOutlet UILabel *longLabel;
}
@end
That is all the interface building we need to do. At this point you need to add the Core Location framework, you can do this by right clicking on the "Frameworks" group and going to Add > Existing Frameworks... This will bring up a browse window, CoreLocation.framework should be an option on the right hand side. This is the framework used to get a hold of location data.
The Core Location framework has only a few classes in it, the most important being CLLocationManager. The CLLocationManager class handles sending out updates to a delegate anytime the location is changed. Since it uses the delegate pattern we need to say that our controller implements the CLLocationManagerDelegate protocol - this is done in the header. The only other thing we need to add to the header is an instance variable for the location manager. Our completed header file is below.
#import <CoreLocation/CoreLocation.h>
@interface WhereAmIViewController : UIViewController
<CLLocationManagerDelegate>{
CLLocationManager *locationManager;
IBOutlet UILabel *latLabel;
IBOutlet UILabel *longLabel;
}
@end
The rest of our code is going to be added to our controller implementation file. First, we have to setup the location manager. This includes allocating a new one and initializing some properties on it. We then have to tell it to start updating the delegate. This is all done inside the viewDidLoad method.
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
You can see above we set the delegate to our self. The second and third properties define how often the manager will update the location. distanceFilter defines how far the location has to move before it will send out an update, kCLDistanceFilterNone means it will always send an update no matter how far the location moves. The last property, desiredAccuracy, decides how accurate the location on the phone needs to be in order to be included as an update, I have it set to kCLLocationAccuracyHundredMeters (100 m).
If you look at the delegate protocol you will see there are several methods that can be implemented, but really the only one that we need to implement is:
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
The delegate method above will be called when there is a new location available. You will notice we get both the old and new locations coming in as CLLocation objects. A CLLocation object has the coordinates, accuracy, altitude, and a timestamp. We are only interested in the coordinates - which has the latitude and longitude. The complete code for our delegate method is below, I will go into more details afterwords.
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
int degrees = newLocation.coordinate.latitude;
double decimal = fabs(newLocation.coordinate.latitude - degrees);
int minutes = decimal * 60;
double seconds = decimal * 3600 - minutes * 60;
NSString *lat = [NSString stringWithFormat:@"%d° %d' %1.4f\"",
degrees, minutes, seconds];
latLabel.text = lat;
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
NSString *longt = [NSString stringWithFormat:@"%d° %d' %1.4f\"",
degrees, minutes, seconds];
longLabel.text = longt;
}
Basically, we take the location and turn the degrees into degrees, minutes, and seconds then display the value in the correct label. We're using fabs instead of abs to get the absolute value since we need the decimal value. The math is pretty simple. Each degree is 60 minutes or 3600 seconds. We start by chopping off the degrees then calculating the whole number of minutes and finish by calculating seconds. Using simple NSString stringWithFormat we create a nice pretty output location string. The final thing we do is set the text of the correct label.
With that, everything seems to be done. We have built the simplest location application you can, but it teaches you how use the core location framework. The framework also includes heading (direction pointed) information but we didn't take a look at this. It works in pretty much the exact same manner. As always, the source code is available below for download. If you have any questions feel free to leave comment.
10/31/2009 - 08:59
Great tutorials, thanks. I'm trying to implement a map that is on a second view I've created. It's a view based app that opens to a launch pad with some buttons to do a few things. One of the buttons opens up the "map view". I can't seem to figure out how to implement a map that zooms into the current location and has a floating annotation (kind of like your seismic annotations).
My two files are setup to open the other views I've created and that seems to be OK.
"LaunchPadViewController.h"
"LaunchPadViewController.m"
It's just when I click the Map button, I'm only presented with the standard map (because I've added MKMapView in IB to the UIView).
All the tutorials I've seen online show how to do this from a main view, but when I try to do it in a "second view", I can't seem to make the link between the main view "launch pad" and the map view I've created.
I hope that made sense.
Thoughts / help?
03/27/2010 - 06:43
Hello..
How I can enforce my location application to use GPS, not relying on cell tower triangulation or Wi-Fi?
Thanks ,,
03/31/2010 - 14:03
"How I can enforce my location application to use GPS, not relying on cell tower triangulation or Wi-Fi?"
The locations service in iPhone works in one of the three ways, from cell triangulation, wifi hot spots or the GPS. They have varying accuracies(GPS being most accurate) but also varying battery consumption(GPS again consuming the most) so by forcing the horizontal accuracy to be KCLLH.A.Best, you can get the GPS. check out the docs,
http://developer.apple.com/iphone/library/documentation/CoreLocation/Reference/CLLocation_Class/CLLocation/CLLocation.html#//apple_ref/doc/c_ref/CLLocationAccuracy
05/31/2010 - 04:34
Its not giving correct longitude and latitude for UK regions
Can you help me out to find it correctly.
Thanks
08/13/2010 - 05:33
"HELLO, GREAT TUTORIAL MAN..
BUT I HAVE SOME ERROR REGARDING THE LOCATION MANAGER.
BELOW IS MY CODE SNIPPET.
if (locationManager != nil) {
return locationManager;
}
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
[locationManager startUpdatingLocation];
return locationManager;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
mUserCurrentLocation = [[CLLocation alloc] init];
self.mUserCurrentLocation = newLocation;
[self uploadUserCurrentLocationToServer];
[manager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"Error: %@", [error description]);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error getting Current Location" message:@"Please check your Internet connection" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alertView show];
[alertView release];
}
IN ABOVE CODE, I GET THE ALERT FOR ERROR. WHICH IS IN DIDFAILWITHERROR METHOD.
THIS MEANS THAT THERE MUST BE SOME FAULT WITH MY ABOVE CODE FOR LOCATION MANAGER.
SO WOULD YOU PLEASE HELP ME TO FIND THE USER'S CURRENT LOCATION.
THANK YOU.
WAITING FOR YOUR REPLY...
08/21/2010 - 02:05
Great tutorial.
The app runs fine but even on emulator or on Device, the same output is seen. I am not able to see the updated location. Any pointers.
I also tried other examples available, every time my phones location points to the values shown in the above app.
01/25/2011 - 15:03
Hi this tutorial is very helpful.
But can I update cordinates in labels with a timer or with a button??? Please help me.
02/04/2011 - 05:15
It is not showing location in iOS version 4. anybody have solution for that?
02/04/2011 - 05:58
Hi this tutorial is nice.
The current location is showing in ios3.0 version simulator only but not in ios4.0 version simulator?can u help me...Please
02/04/2011 - 15:18
Anybody have a solution for iOS4?
02/17/2011 - 07:52
I have used this code to get current location but it's work in ios3.0 version not work ios4.0 so any body have any solution to get current location in ios4.0 version
02/17/2011 - 13:29
I will try to have this updated for iOS4 here really soon.
03/02/2011 - 20:48
That would be awesome!
03/08/2011 - 02:17
hiiiiiiiii
i have solved this problem this code do not work on Iphone simulator 4.0 but its work on Iphone 4.0
build this code in ios4.0 and install in iphone
check iphone settings.
first of all go to setting tab and go to General tab after going to General tab go to Location Services and look up your app name and on location service
its work perfect.
08/29/2011 - 02:47
Hey i've same problem to obtain current location Longitude and Latitude actually i want to draw route on my apps from current position to specific location i tried many way in my apps bt i can't get result
i'm using iOS 4.0
also tried in iOS 4.2
i hope that u'll reply asap.
Thanks!! :)
02/17/2011 - 12:23
Hi
I tested this app . But this app is not returning the accurate current location , Could you tell me how can i find current location with GPS not with the CLLocation Delegate, Sorry i m novice in iPhone sdk . I hope you will help me
Thanks in advance :)
02/17/2011 - 13:29
If you're using the emulator it will always show your location at Apple's headquarters.
03/08/2011 - 02:49
i have get latitude and longitude of current location but i don't get blue dot and circle on map and i have get current latitude and longitude and pass in web service URL and according to current latitude and longitude i have drooped annotation pin on map in 2.0 miles but i don't get blue dot and circle of current location on map
09/26/2011 - 00:24
hi mukesh i'm having the same problem so if you got the reason can you help me on the question i had asked on stackoverflow on below mentioned link
http://stackoverflow.com/questions/7550777/annotation-on-current-location
03/10/2011 - 16:31
simple and efective :) Tnks
04/13/2011 - 04:55
is it possible that within the app if user wants to enable or disable the location update functionality.that is whenever user wants he can use location update service & whenever doesnt want can turn off that one.
05/09/2011 - 00:01
is it possible to test the application for getting the current location and display it in iphone simulator.
Thanks
06/24/2011 - 07:10
very helpful; Thanks
07/07/2011 - 18:24
Hi,
Good post.
I am working on an application that involves getting the user's location based on gps. The problem that I am facing is that I need to get the user's position at certain time intervals (like for every 3 min). How do I implement that? Because so far I have seen, the locationManager provides options for the distance filter and not based on time. I am not sure whether the other two options - significant location changes and monitoring regions actually work in my iphone. So could you help me to implement thecode for getting the user's location periodically??Thanks in advance.
08/29/2011 - 01:24
Hey,
Is there any to activate GPS On iphone simulator 4.3 ?
08/29/2011 - 08:24
No, the location on the simulator always returns a fixed location.
11/03/2011 - 04:57
the app works well n i am able to get the latitude n longitude of my location but after somtime i get the below mentioned error and the app shuts down automatically.
i request you to help me
Error launching remote program: failed to get the task for process 3952.
01/12/2012 - 17:10
Hi,
This a nice tutorial.. But handling the "did update to location" can easier.. Here is a tutorial wich gives you the longitude and latitude in a very easy way..
http://www.altinkonline.nl/tutorials/xcode/corelocation/find-longitude-and-latitude-by-corelocation-xcode/
Add Comment
[language] [/language]
Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]
See here for supported languages.
Javascript must be enabled to submit anonymous comments - or you can login.