Tuesday, 5 August 2014

How To Get the User's Current Location and Related Address


This article will show you how to add GPS capability in your iPhone app and retrieve the user’s current location. Also translate the GPS coordinate into street address.

The Core Location framework provides the necessary Objective-C interfaces for obtaining information about the user’s location. With the GPS coordinate obtained, you can make use of the API to decode the actual street or utilize the Map framework to further display the location on Map.

Add MapKit and CoreLocation framework in your project. Core Location framework, that you’ve just added, allows you to retrieve the user’s current location in the form of latitude and longitude. It can even give you continuous location update if the user is on the move. To work with the Core Location framework, our view controller should conform to the CLLocationManagerDelegate protocol. This protocol defines methods used to receive location and heading updates from a CLLocationManager object.

Add MapView on your View Controller. Now set the delegate and outlet of your map view. Add MKMapViewDelegate and CLLocationManagerDelegate.


Declare an instance variable and name it as locationManager. The CLLocationManager is the object that provides you the location data.

Once you initialize a CLLocationManager object, you can simply call the startUpdatingLocation method to the location service. The service will then continuously send your application a stream of location data.

see code below:


// .h file


#import <UIKit/UIKit.h>

#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>


@interface GPSViewController : UIViewController<MKMapViewDelegate,CLLocationManagerDelegate>
{

    CLLocationManager *locationManager;

    //to find address of current location
     CLGeocoder *geocoder;
     CLPlacemark *placemark;

}



@property (strong, nonatomic) IBOutlet MKMapView *myMapView;



@end


// .m File


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
  
    
    [self.view setBackgroundColor:[UIColor clearColor]];
    
    
    [self.myMapView setMapType:MKMapTypeStandard];
    //self.myMapView.showsUserLocation = YES;   // to show pin point on current location
    
    locationManager = [[CLLocationManager alloc]init];
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    locationManager.delegate = self;

    //request for location updates
    [locationManager startUpdatingLocation];
    
    
    
    //set region
    CLLocationCoordinate2D _coordinate = locationManager.location.coordinate;
    MKCoordinateRegion extentsRegion = MKCoordinateRegionMakeWithDistance(_coordinate, 50, 50);
    
    
    extentsRegion.span.latitudeDelta = 0.02f;
    
    extentsRegion.span.longitudeDelta = 0.02f;
    
    extentsRegion.center = _coordinate;
    
    [self.myMapView setRegion:extentsRegion animated:YES];
    
    
    //set annotation
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
    
    NSString *sttt = [[NSString alloc]initWithFormat:@"%f,%f",_coordinate.latitude,_coordinate.longitude];
    
    annotation.title = @"Main Title";
    annotation.subtitle = sttt;
    
    annotation.coordinate = _coordinate;
    
    [self.myMapView addAnnotation:annotation];



   geocoder = [[CLGeocoder alloc] init];



}





To capture the location event, we have to implement the delegate methods as defined in the protocol.


#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
    UIAlertView *errorAlert = [[UIAlertView alloc]
                                    initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}



- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;
    
    if (currentLocation != nil) 
   {
        NSLog(@"longitude: %@", [NSString 
                                        stringWithFormat:@"%.8f",currentLocation.coordinate.longitude]);
        
        NSLog(@"latitude: %@",                 
                                           [NSString stringWithFormat:@"%.8f",currentLocation.coordinate.latitude]);
    }

    // Stop Location Manager
    [locationManager stopUpdatingLocation];



     /*
    // Reverse Geocoding
    NSLog(@"Resolving the Address");
    
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
        NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0)
        {
            placemark = [placemarks lastObject];
            
            
            
            NSLog(@"Address: %@", [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@",
                                   placemark.subThoroughfare, placemark.thoroughfare,
                                   placemark.postalCode, placemark.locality,
                                   placemark.administrativeArea,
                                   placemark.country]);
            
        } else {
        
            NSLog(@"%@", error.debugDescription);
        }
    } ]; 
*/
    
    
    
    
    
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error)
     {
         
         NSLog(@"Found placemarks: %@, error: %@", placemarks, error);


         NSLog(@"placemarks=%@",[placemarks objectAtIndex:0]);
         CLPlacemark *placemark1 = [placemarks objectAtIndex:0];
         
         NSLog(@"placemark.ISOcountryCode =%@",placemark1.ISOcountryCode);
         NSLog(@"placemark.country =%@",placemark1.country);
         NSLog(@"placemark.postalCode =%@",placemark1.postalCode);
         NSLog(@"placemark.administrativeArea =%@",placemark1.administrativeArea);
         NSLog(@"placemark.locality =%@",placemark1.locality);
         NSLog(@"placemark.subLocality =%@",placemark1.subLocality);
         NSLog(@"placemark.subThoroughfare =%@",placemark1.subThoroughfare);



         
         if (error == nil && [placemarks count] > 0)
         {
             placemark = [placemarks lastObject];
             
             // strAdd -> take bydefault value nil
             NSString *strAdd = nil;
             
             if ([placemark.subThoroughfare length] != 0)
                 strAdd = placemark.subThoroughfare;
             
             if ([placemark.thoroughfare length] != 0)
             {
                 // strAdd -> store value of current location
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark thoroughfare]];
                 else
                 {
                     // strAdd -> store only this value,which is not null
                     strAdd = placemark.thoroughfare;
                 }
             }
             
             if ([placemark.postalCode length] != 0)
             {
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark postalCode]];
                 else
                     strAdd = placemark.postalCode;
             }
             
             if ([placemark.locality length] != 0)
             {
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark locality]];
                 else
                     strAdd = placemark.locality;
             }
             
             if ([placemark.administrativeArea length] != 0)
             {
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark administrativeArea]];
                 else
                     strAdd = placemark.administrativeArea;
             }
             
             if ([placemark.country length] != 0)
             {
                 if ([strAdd length] != 0)
                     strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark country]];
                 else
                     strAdd = placemark.country;
             }
             
             
             NSLog(@"Address : %@", strAdd);
             
         }
         
     }];


}






Finding the Address

The CLGeocoder class provides services for converting between a GPS coordinate and the user-readable address of that coordinate. By specify the latitude and longitude of a given location, you can use CLGeocoder to find a user-readable address. The result (i.e. the address) returned by CLGeocoder is saved in a CLPlacemark object.
Back to your Xcode project. Add two instance variables: geocoder and placemark.

see all steps in upper code.
Initialize the “geocoder” in the “viewDidLoad” method.
Update the “didUpdateToLocation” method to include the code for reverse geocoding.

Upon completion of a geocoding request, the completionHandler will be invoked automatically. The resolved address is saved in CLPlacemark array. Placemark data includes information such as the country, state, city, and street address. So we simply pick the CLPlacemark object from the array and show the address in the address label.

You can use the “stopUpdatingLocation” method to disable the location update. we can stop the location update once we retrieve the current location.

Try to run the app again and check out the output message in the output area. You should notice that the “didUpdateToLocation” is called once and stopped.








No comments:

Post a Comment