Get device location (countries only) in iOS

I need to get the location in the country of the iOS device.

I am trying to use CoreLocation with MKReverseGeocoder. However, this seems to return quite often. And I only need a country, there is no need for streets, etc.

How can this be done in a more stable way?

+44
ios core-location
Dec 16 '11 at 12:58
source share
10 answers

NSLocale is just a setting of existing regional settings, this does not mean that you are in the country in which you are.

Use CLLocationManager to get the current location and CLGeocoder to do reverse geocoding. You can get the name of the country from here.

+30
Dec 16 2018-11-12T00:
source share
 NSString *countryCode = [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode]; 

will give you an identifier, for example, for example. "USA" (USA), "ES" (Spain), etc.




In Swift 3 :

 let countryCode = NSLocale.current.regionCode 

In Swift 2.2 :

 let countryCode = NSLocale.currentLocale().objectForKey(NSLocaleCountryCode) as String 

Compared to the solution based on CLLocationManager, this approach has its pros and cons. The basic principle is that it does not guarantee that it is a physical device if the user configures it differently. However, this can also be regarded as a professional, because instead it shows which country the user is mentally and culturally - so if, for example, I am going abroad on vacation, then the area is still sent to my home country. However, a fairly large professional is that this API does not require user permission, such as CLLocationManager. Therefore, if you have not yet received permission to use the user's location, and you cannot really justify opening a pop-up dialog box on the user's face (or they already rejected this pop-up window, and you need a backup), then this is probably an API that you want to use. Some typical use cases for this can be personalization (for example, culturally relevant content, default formats, etc.) and analytics.

+77
Dec 16 2018-11-12T00:
source share

@ Denis's answer is good - here is some kind of code that translates his answer into practice. This is for a custom class that you configured to comply with the CLLocationManagerDelegate protocol. It’s a little simplified (for example, if the location manager returns multiple locations, it just comes with the first one), but should give people a decent start ...

 - (id) init //designated initializer { if (self) { self.locationManager = [[CLLocationManager alloc] init]; self.geocoder = [[CLGeocoder alloc] init]; self.locationManager.delegate = self; [self.locationManager startMonitoringSignificantLocationChanges]; } return self; } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { if (locations == nil) return; self.currentLocation = [locations objectAtIndex:0]; [self.geocoder reverseGeocodeLocation:self.currentLocation completionHandler:^(NSArray *placemarks, NSError *error) { if (placemarks == nil) return; self.currentLocPlacemark = [placemarks objectAtIndex:0]; NSLog(@"Current country: %@", [self.currentLocPlacemark country]); NSLog(@"Current country code: %@", [self.currentLocPlacemark ISOcountryCode]); }]; } 
+12
May 30 '14 at 12:32
source share

Here's an alternative, perhaps too circumventing method. Other solutions are based on manual settings (NSLocale) or when requesting permission to use location services that may be deprived (CLLocationManager), so they have disadvantages.

You can get the current country based on your local time zone. My application interacts with a server running Python with pytz installed, and this module provides a country code dictionary for timezone strings. I really need the server to know the country, so I don’t need to configure it completely on iOS. On the Python side:

 >>> import pytz >>> for country, timezones in pytz.country_timezones.items(): ... print country, timezones ... BD ['Asia/Dhaka'] BE ['Europe/Brussels'] BF ['Africa/Ouagadougou'] BG ['Europe/Sofia'] BA ['Europe/Sarajevo'] BB ['America/Barbados'] WF ['Pacific/Wallis'] ... 

On the iOS side:

 NSTimeZone *tz = [NSTimeZone localTimeZone]; DLog(@"Local timezone: %@", tz.name); // prints "America/Los_Angeles" 

I have a server that sends the name of the local time zone and looks it up in the pytz dictionary of country_timezones.

If you are creating an iOS dictionary version available in pytz or some other source, you can use it to immediately search for the country code without the help of a server, based on the time zone settings that are often relevant.

Maybe I'm wrong in NSLocale. Does it provide a country code with regional formatting options or time zone settings? If the latter, then this is just a more complicated way to get the same result ...

+6
Jul 19 '12 at 23:23
source share

Following are the answers of @Denis and @Matt for Swift 3 solution:

 import UIKit import CoreLocation class ViewController: UIViewController, CLLocationManagerDelegate { let locationManager = CLLocationManager() let geoCoder = CLGeocoder() override func viewDidLoad() { super.viewDidLoad() locationManager.requestAlwaysAuthorization() if CLLocationManager.locationServicesEnabled() { locationManager.delegate = self locationManager.startMonitoringSignificantLocationChanges() } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let currentLocation = locations.first else { return } geoCoder.reverseGeocodeLocation(currentLocation) { (placemarks, error) in guard let currentLocPlacemark = placemarks?.first else { return } print(currentLocPlacemark.country ?? "No country found") print(currentLocPlacemark.isoCountryCode ?? "No country code found") } } } 

Remember to also set NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription in Info.plist !

+6
Dec 28 '16 at 21:11
source share
 NSLocale *countryLocale = [NSLocale currentLocale]; NSString *countryCode = [countryLocale objectForKey:NSLocaleCountryCode]; NSString *country = [countryLocale displayNameForKey:NSLocaleCountryCode value:countryCode]; NSLog(@"Country Locale:%@ Code:%@ Name:%@", countryLocale, countryCode, country); //Country Locale:<__NSCFLocale: 0x7fd4b343ed40> Code:US Name:United States 
+4
Mar 17 '15 at 10:49
source share

For Swift 3, this is even simpler:

 let countryCode = Locale.current.regionCode 
+3
Dec 06 '16 at 13:45
source share

You can get NSTimeZone from CLLocation: https://github.com/Alterplay/APTimeZones and works locally.

+1
Oct 23 '13 at 14:19
source share

If you are only interested in telephones, then the technique mentioned here may be useful to you: Determine the country of the iPhone user

0
Mar 07 2018-12-12T00:
source share

Here's a quick loop in Swift 3 that returns a complete list of country codes.

 let countryCode = NSLocale.isoCountryCodes for country in countryCode { print(country) } 
-one
May 02 '17 at 9:26 a.m.
source share



All Articles