There will be a time when we would have to get the address of location from lattitude and longitude value. This concept is called Reverse geocoding. Well as usual this post is again about the mistake that I made and the solution that I got for it. Apple has introduced CLGeocoder class from ios 5.0 onwards. According to reference doc:

The CLGeocoder class provides services for converting between a coordinate (specified as a latitude and longitude) and the user-friendly representation of that coordinate.

For reverse geocoding there is a method where you provide location and it will convert:

- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler

Now I’ll start the boring tale of my mistake. If you see the reverseGeocodeLocation, it takes CLLocation as parameter which represent location data that also consist our latitude and longitude information. Now I had just lat and long value that I was receiving from my json object. So I had a simple requirement to parse those values and convert them to meaningful street address. I have a float values of lat and long, reverseGeocodeLocation takes CLLocation as parameter. I need to somehow convert float values to CLLocation or make CLLocation from my float values. So here is what I did first:

CLLocation *coordinates = [[CLLocation alloc]init];
coordinates.coordinate.latitude = [@"41.409261" floatValue];
coordinates.coordinate.longitude = [@"2.163517" floatValue];

But there lies a big problem. The thing is coordinate property(CLLocationCoordinate2D) is read only so I cannot assign my float values to respective lat and long directly. So now what I had to do was initialize CLLocation from CLLocationCoordinate2D which is a structure. This is how I represented my lat and long with CLLocationCoordinate2D:

CLLocationCoordinate2D coordinate;
coordinate.latitude = [@"41.409261" floatValue];
coordinate.longitude = [@"2.163517" floatValue];

Initialize CLLocation with newly created coordinate:

CLLocation *currentLocation = [[CLLocation alloc]initWithCoordinate:coordinate altitude:1 horizontalAccuracy:1 verticalAccuracy:-1 timestamp:[NSDate date]];

My location is ready now and I just pass it to reverseGeocodeLocation and on complete handler I receive my meaningful street address:

[self.geocoder reverseGeocodeLocation: currentLocation completionHandler:
     ^(NSArray *placemarks, NSError *error) {      
         //Get nearby address
         CLPlacemark *placemark = [placemarks objectAtIndex:0];
         
         NSString *addressName = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];

         NSLog(@"My location name is %@",addressName);
         }];