Reputation: 2482
In my iOS App, I need to obtain the user current country.
I know that I can use CLLocation
to retrieve the location and then reverseGeocodeLocation
to get the country, but it will not work if the user doesn't authorize my app to get his location.
I could maybe use (Locale.current as NSLocale).object(forKey: NSLocale.Key.countryCode)
;
but I wonder if the countryCode change when the user travels or only when he manually change his settings?
Is it possible to retrieve this information from the current carrier operator ?
Upvotes: 1
Views: 601
Reputation: 1049
I managed to get the country without asking for location permissions using the following approach:
import MapKit
class CountryDectectorViewController: UIViewController {
var didDetectCountryCode: ((String?) -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
// Map view setup
let mapView = MKMapView()
view.addSubview(mapView)
mapView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
mapView.topAnchor.constraint(equalTo: view.topAnchor),
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
mapView.layoutIfNeeded()
// Reverse geocoding map region center
let location = CLLocation(
latitude: mapView.region.center.latitude,
longitude: mapView.region.center.longitude
)
CLGeocoder().reverseGeocodeLocation(location) { placemarks, _ in
self.didDetectCountryCode?(placemarks?.first?.isoCountryCode)
}
}
}
To ISO Country Code can be then obtained using:
let controller = CountryDectectorViewController()
controller.loadViewIfNeeded()
controller.didDetectCountryCode = { countryCode in
print(countryCode)
}
Some context
I realised that UIKit has this information already because everytime the MKMapView
is shown, the region is automatically set to fit the current user's country. Using this hypothesis I needed to find a solution to load the map without presenting it and then to reverse geocode the center coordinates to identify the country.
I implemented this solution taking into consideration the following limitations I found:
Upvotes: 0
Reputation: 2566
You can find the country code using carrier by using this
CTTelephonyNetworkInfo *netInfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = [netInfo subscriberCellularProvider];
NSString *mcc = [carrier mobileCountryCode];
Upvotes: 5