when - Abrufen des Gerätestandorts(nur Land) in iOS




swift location manager delegate (8)

Ich muss den Standort eines iOS-Geräts ermitteln.

Ich habe versucht, CoreLocation mit MKReverseGeocoder zu verwenden. Dies scheint jedoch ziemlich häufig fehlerhaft zurückzukehren. Und ich brauche nur das Land, keine Straßen und so.

Wie kann dies stabiler gemacht werden?


@ Denis 's Antwort ist gut - hier ist ein Code, der seine Antwort in die Praxis umsetzt. Dies ist für eine benutzerdefinierte Klasse, die Sie so eingestellt haben, dass sie dem CLLocationManagerDelegate Protokoll entspricht. Es ist ein wenig vereinfacht (zB wenn der Standortmanager mehrere Standorte zurückgibt, geht es einfach mit dem ersten Standort), sollte den Leuten aber einen guten Start geben ...

- (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]);
    }];
}

@Rauben

let locale = Locale.current
let code = (locale as NSLocale).object(forKey: NSLocale.Key.countryCode) as! String?

Wenn Sie diesen Code verwenden, erhalten Sie den Ländercode für Ihre Region. Wenn Sie sich nicht beruhigt haben, ändern Sie ihn einfach in Telefoneinstellung -> Allgemein -> Sprache & Region, und legen Sie die gewünschte Region fest


Hier die Antworten von @ Denis und @ Matt für eine Swift 3- Lösung:

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")
        }
    }
}

Vergessen Sie nicht, NSLocationAlwaysUsageDescription oder NSLocationWhenInUseUsageDescription in Info.plist !


Hier ist eine alternative, vielleicht zu umständliche Methode. Die anderen Lösungen basieren auf manuellen Einstellungen (NSLocale) oder auf dem Anfordern der Erlaubnis, Standortdienste zu verwenden, die abgelehnt werden können (CLLocationManager), so dass sie Nachteile haben.

Sie können das aktuelle Land basierend auf der lokalen Zeitzone abrufen. Meine App stellt eine Schnittstelle zu einem Server her, auf dem Python ausgeführt wird, auf dem pytz installiert ist. Dieses Modul enthält ein Wörterbuch mit Ländercodes zu Zeitzonen. Ich brauche nur, dass der Server das Land kennt, sodass ich es nicht vollständig auf iOS einrichten muss. Auf der Python-Seite:

>>> 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']
...

Auf der iOS-Seite:

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

Ich habe meinen Server den Namen der lokalen Zeitzone eingeben und im pytz country_timezones-Wörterbuch nachschlagen.

Wenn Sie eine iOS-Version des Wörterbuchs in pytz oder einer anderen Quelle verfügbar machen, können Sie diese ohne Hilfe eines Servers auf der Grundlage der Zeitzoneneinstellungen, die häufig auf dem neuesten Stand sind, sofort nach dem Ländercode suchen.

Ich kann NSLocale jedoch falsch verstehen. Gibt es den Ländercode durch regionale Formatierungsvorgaben oder Zeitzoneneinstellungen? Wenn letzteres, dann ist dies nur ein komplizierter Weg, um das gleiche Ergebnis zu erzielen ...



Swift 4.0-Code zum Abrufen des Ländernamens gemäß der Regionseinstellung:

    let countryLocale = NSLocale.current
    let countryCode = countryLocale.regionCode
    let country = (countryLocale as NSLocale).displayName(forKey: NSLocale.Key.countryCode, value: countryCode)
    print(countryCode, country)

Drucke: Optional ("NG") Optional ("Nigeria"). // für die Region Nigeria eingestellt


NSLocale ist nur eine Einstellung zu den aktuell verwendeten regionalen Einstellungen. Das bedeutet nicht, in NSLocale Land Sie sich gerade befinden.

Verwenden Sie CLLocationManager , um den aktuellen Standort CLGeocoder , und CLGeocoder zum Durchführen einer umgekehrten Geocodierung. Dort können Sie den Ländernamen erhalten.


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




core-location