I'm creating a global app and one of the initial screens will detect which country the user is in. I'm using reverseGeocodeLocation for this.
[geocoder reverseGeocodeLocation:[locations lastObject] completionHandler:^(NSArray *placemarks, NSError *error)
{
CLPlacemark *placemark = [placemarks lastObject];
country = placemark.country;
[locationManager stopUpdatingLocation];
if (country != NULL) {
[self showAlert];
}
else {
[self showActionSheet];
}
}];
When in the UK placemark.country will return "United Kingdom". I'm trying to find a list of the return strings for each country. I couldn't find anything on the apple documentation.
You could write code in 2 minutes to get the list for yourself, iterate through the list of ISO country codes and then convert them from an ISO code to the country name and NSLog each one.
The name displayed would of course only be the name for the current language locale setting on your device, in your case English.
Related
In my application I want the exact lattitude and longitude of given address using forward geocoding in IOS in Objective-C.
I had used forward geocoding in my application but it is not giving the exact address. this is my code of forward geocoding
-(void)detectlocation:(NSString*)address
{
CLGeocoder *geocoder=[[CLGeocoder alloc]init];
[geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error)
{
if(!error)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"%f",placemark.location.coordinate.latitude);
NSLog(#"%f",placemark.location.coordinate.longitude);
self.latitude4=placemark.location.coordinate.latitude;
self.longitude4=placemark.location.coordinate.longitude;
NSLog(#"%#",[NSString stringWithFormat:#"%#",[placemark description]]);
}
}];
}
Thanks In Advance
You can access placemark properties for a more accurate location.
This is swift, but the same is for objective-c
Declare and initiate your CLLocationMager* inside the viewDidLoad method.
I recommend to use:
#property YourCustomLocation* foundedLocation;
in order to "save" data of the place that has been found.
Then try this inside your method:
[self.geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
//if 1+ "places" have been found:
if ([placemarks count] > 0) {
//save the first place that has been found
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//save location from the placemark
CLLocation *location = placemark.location;
//save coordinates from location
CLLocationCoordinate2D coordinate = location.coordinate;
//Do more stuffs...like:
self->_foundedLocation = [[YouCustomLocation alloc]initLocationWithLatitude:coordinate.latitude Longitude:coordinate.longitude];}
}];
Remember that forward-geocoding works with blocks, so unless you use __block directive near the variable you won't be able to "save the location" on a variable declared outside the block.
I am trying to get user's region code in swift 3 by using:
Locale.current.regionCode
Unfortunately regionCode is nil, do you have an idea why?
And what should I do to obtain it?
Thanks a lot.
For those looking for solutions at SIMULATOR, go to "Settings > General > Language & Region" and change the region.
It worked for me and other people.
For a weird unknown reason, some simulators doesn't return the region until it changes at least once.
I don't know if it works at real device as well, because I did not had this problem on real device.
I ran into the same issue and as it turns out it was because I set my Scheme to a specific language. If you set both, Application Language & Application Region to "System Language / Region" it should work.
Many of the properties on Locale can return nil for various reasons on iOS (and Android).
You may also use objectForKey:NSLocaleCountryCode to query the country code.
// code may be nil
NSString *code = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
It's a good idea to have a fallback logic to find countryCode with CoreTelephony.
CTCarrier *carrier = [[CTTelephonyNetworkInfo new] subscriberCellularProvider];
NSString *countryCode = carrier.isoCountryCode;
Or/And with reverse geocode:
// CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
__block CLLocation *location = [locations firstObject];
[[[CLGeocoder alloc] init] reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (!error && placemarks.count > 0) {
CLPlacemark *placemark = [placemarks firstObject];
// Use placemark.country;
// Use placemark.ISOCountryCode;
}
}
}
For instance, on Android version of corresponding region query for Locale, it's nil for many of the rooted devices.
The documentation for regionCode states
The region code of the locale, or nil if it has none.
Some locales simply do not have a region (aka country) code. However I don't know which ones do not.
the latest Xcode/SDK iOS download is no longer providing the 'country' string.
- (void)GEOLocator
{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
CLLocation *myLocation = [[CLLocation alloc] initWithLatitude:currentCentre.latitude longitude:currentCentre.longitude];
[geocoder reverseGeocodeLocation:myLocation completionHandler:^(NSArray *placemarks, NSError *error)
{
// the returned error code is 0
NSLog(#"%ld",(long)error.code);
// there’s only one entry in the placemarks NSArray
NSLog(#"placemarks count(%lu)",(unsigned long)[placemarks count]);
CLPlacemark *placemark = [placemarks firstObject];
// and the country property is null
NSLog(#"placemark.country(%#)",placemark.country);
}
];
}
currentCentre.latitude and currentCentre.longitude is hardcoded to downtown San Francisco: these have been proven to work.
the NSLog output’s are:
2015-08-29 15:47:48.299 MyApp[10128:548448] 0
2015-08-29 15:47:48.299 MyApp[10128:548448] placemarks count(1)
2015-08-29 15:47:48.300 MyApp[10128:548448] placemark.country((null))
this code sequence is about as simple as it gets, yet the latest Xcode/iOS download no longer can tell me what country I’m in?!
if this isn't correct can someone please post the correct way to retrieve 'county' from CLLocation?
the core problem is that in Xcode/Simulator you can set lat/long values in multiple places begging the question: what happens when these settings conflict?
the simulator had me out in the middle of the North Atlantic! which explains why the 'country' (as well as several others) were null. the difficulty lie in setting a test lat/long value and the fact one can do that in multiple places: 1) Edit Scheme, 2) the Simulator Loction menu item, and 3) directly in source.
it would be nice to set test lat/long's in one place and everything then just works.
I got the user location, now I want to, somehow, identify the nearest intersection/cross.
For example: I'm at 5th Av. between the 44 & 45. The Mapkit will give me the 5th av as the current address but I can't find a way to detect the two intersections.
Is this possible?
I'm not stuck to the map kit, and the only thing I want is a method or class to return the name of the streets. So if there is another service or kit to determine that, it will be perfect.
CLLocation *currentLocation = [locations lastObject];
[_geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
if (error == nil && [placemarks count] > 0)
{
_currentPlaceMark = [placemarks lastObject];
_posicaoAtual.text = [NSString stringWithFormat:#"%# | %#-%#",
[_currentPlaceMark valueForKey:#"thoroughfare"],
[_currentPlaceMark valueForKey:#"locality"],
[_currentPlaceMark valueForKey:#"administrativeArea"]];
}
} ];
I am trying to Reverse geocode location from Lat/Long value that I get earlier in the App and I would like from this coordinate to find the city name, country name and ISO.
I am currently using CLLocationManager to get actual location information with the folowing code:
//Auto geolocation and find city/country
locationManager.delegate=self;
//Get user location
[locationManager startUpdatingLocation];
[self.geoCoder reverseGeocodeLocation: locationManager.location completionHandler:
^(NSArray *placemarks, NSError *error) {
//Get nearby address
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to hold address
locatedAtcountry = placemark.country;
locatedAtcity = placemark.locality;
locatedAtisocountry = placemark.ISOcountryCode;
//Print the location to console
NSLog(#"Estas en %#",locatedAtcountry);
NSLog(#"Estas en %#",locatedAtcity);
NSLog(#"Estas en %#",locatedAtisocountry);
[cityLabel setText:[NSString stringWithFormat:#"%#,",locatedAtcity]];
[locationLabel setText:[NSString stringWithFormat:#"%#",locatedAtcountry]];
//Set the label text to current location
//[locationLabel setText:locatedAt];
}];
It is working perfectly but, It is possible to do the same from Long/Lat value that I had already saved in the device and not with the current location like on the actual code ?
Update and solution:
Thanks Mark for the answer, I finally use the following code to get info from saved coordinate:
CLLocation *location = [[CLLocation alloc] initWithLatitude:37.78583400 longitude:-122.40641700];
[self.geoCoder reverseGeocodeLocation: location completionHandler:
^(NSArray *placemarks, NSError *error) {
//Get nearby address
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to hold address
locatedAtcountry = placemark.country;
locatedAtcity = placemark.locality;
locatedAtisocountry = placemark.ISOcountryCode;
//Print the location to console
NSLog(#"Estas en %#",locatedAtcountry);
NSLog(#"Estas en %#",locatedAtcity);
NSLog(#"Estas en %#",locatedAtisocountry);
[cityLabel setText:[NSString stringWithFormat:#"%#",locatedAtcity]];
[locationLabel setText:[NSString stringWithFormat:#"%#",locatedAtcountry]];
//Set the label text to current location
//[locationLabel setText:locatedAt];
}];
Yes. Create a CLLocation object using the initWithLatitude:longitude: method using your saved lat/lon values, and pass that to reverseGeocodeLocation:.
I am surprised that you say this is working (although, if you're on the simulator, location services are simulated anyway, which might be the reason) because when you call startUpdatingLocation, your implementation of CLLocationManagerDelegate methods like locationManager:didUpdateToLocation:fromLocation: get called. (You've implemented these right?) It is only when this (and other) delegate method is called that you can be certain that you have successfully determined the user's location.
You may want to read up on the CLLocationManagerDelegate protocol and on Location Services best practices as documented by Apple.