Using reverse geocoding is what you need and is straightforward.
Given a class that holds a CLLocation *location property, simply use this code sniper I wrote for one of my project, and you re done.
-(void)loadAddress:(void (^)(NSError *error))completion {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:self.location
completionHandler:^(NSArray *placemarks, NSError *error) {
NSString *address = nil;
if (error) {
self.placemark = nil;
self.address = NSLocalizedString(@"Unknown address.",@"");
}
else {
CLPlacemark * placeMark = [placemarks firstObject];
self.placemark = placeMark;
NSDictionary *d = placeMark.addressDictionary;
address = [(NSArray*)d[@"FormattedAddressLines"] componentsJoinedByString:@" "];
self.address = address;
}
// Call caller
if (completion) completion(error);
}];
}
Note that you will be more interested in getting d[@"State"] rather than d[@"FormattedAddressLines"].
Also note that reverse geocoding requires internet access (it s implemented as a Web service) and is subject to volume limitation. Most likely, you shouldn t exceed more than a couple of calls per minute. If you exceed the quota set by Apple, you ll receive an error.
For your convenience, here are the KV stored by the placeMark.addressDictionary proprerty:
{
City = Millbrae;
Country = "Etats-Unis";
CountryCode = US;
FormattedAddressLines = (
"I-280 N",
"Half Moon Bay, CA 94019",
"Etats-Unis"
);
Name = "I-280 N";
State = CA;
Street = "I-280 N";
SubAdministrativeArea = "San MatU00e9o";
SubLocality = "Bay Area";
Thoroughfare = "I-280 N";
ZIP = 94019;
}