Ortungsdienste funktionieren unter iOS 8 nicht


608

Meine App, die unter iOS 7 einwandfrei funktioniert hat, funktioniert nicht mit dem iOS 8 SDK.

CLLocationManagergibt keinen Standort zurück und ich sehe meine App auch nicht unter Einstellungen -> Standortdienste . Ich habe eine Google-Suche zu diesem Thema durchgeführt, aber es wurde nichts gefunden. Was könnte falsch sein?


Sie können dies auch als Referenz-App für die Lösung github.com/jbanford/ConstantLocationUpdates
ashok vadivelu

19
Ich habe über einige der Änderungen am Standortmanager in iOS 8 hier gepostet
nevan king

2
Sie können versuchen, diese Bibliothek zu verwenden, die die Core Location-APIs vereinfacht, eine schöne blockbasierte Oberfläche bereitstellt und alle Unterschiede zwischen verschiedenen iOS-Versionen normalisiert (vollständige Offenlegung: Ich bin der Autor): github.com/lmirosevic/GBLocation
lms

Ich habe hier eine Referenz gefunden datacalculation.blogspot.in/2014/11/…
iOS Test

2
@nevanking Sie Sir! brauche eine Krone! Ich habe seit der Änderung mit diesem Problem gekämpft und habe noch keinen "Leitfaden" gefunden, wie ich es beheben kann. Das war noob-freundlich. Ihr Leitfaden hat einen Idioten wie mich dazu gebracht, das Problem selbst zu lösen. Vielen Dank für diesen Link.
Patrick R

Antworten:


1086

Am Ende habe ich mein eigenes Problem gelöst.

Anscheinend ist im iOS 8 SDK requestAlwaysAuthorization(für den Hintergrundspeicherort) oder requestWhenInUseAuthorization(Standort nur im Vordergrund) ein Aufruf CLLocationManagererforderlich, bevor Standortaktualisierungen gestartet werden.

Es muss auch sein , NSLocationAlwaysUsageDescriptionoder NSLocationWhenInUseUsageDescriptionSchlüssel in Info.plisteiner Nachricht in der Eingabeaufforderung angezeigt werden. Das Hinzufügen dieser löste mein Problem.

Geben Sie hier die Bildbeschreibung ein

Hoffe es hilft jemand anderem.

BEARBEITEN: Weitere Informationen finden Sie unter: Core-Location-Manager-Changes-in-ios-8


6
Kannst du den genauen Wert teilen, den du in Info.plist aktualisiert hast? Ich kann diesen Schlüssel in meiner Info.plist nicht sehen. Ich habe es hinzugefügt und trotzdem scheint es nicht zu funktionieren. Ich benutze Swift, iOS8 und XCode 6 Beta 4
Vijay Kumar AB

4
@Vjay - Sie müssen die Datei Info.plist in einem Editor bearbeiten und können diese Schlüssel nicht in Xcode festlegen (ab Beta 6).
Kendall Helmstetter Gelner

11
Nur zur Erinnerung: Wenn Sie dem Benutzer keine benutzerdefinierte Erklärung anzeigen möchten, setzen Sie diesen Schlüssel einfach auf eine leere Zeichenfolge.
Nonamelive

7
Sie müssen Ihren locationManager beibehalten, damit er funktioniert. Machen Sie Ihren CLLocationManager zu einer starken Eigenschaft
Vassily

273
Ich 'LIEBE', dass Sie keinen Fehler, keine Warnung, keine Protokollmeldung erhalten, NICHTS, wenn Sie den Plist-Eintrag weglassen. Grundsätzlich hat Apple einen API-Aufruf erstellt, der NICHTS tut, wenn Sie nicht über den entsprechenden Plist-Eintrag verfügen. Vielen Dank an @OrtwinGentz, der das herausgefunden hat.
MobileVet

314

Ich zog mir mit dem gleichen Problem die Haare aus. Xcode gibt Ihnen den Fehler:

Es wird versucht, MapKitStandortaktualisierungen zu starten, ohne zur Standortautorisierung aufzufordern. Muss anrufen -[CLLocationManager requestWhenInUseAuthorization]oder -[CLLocationManager requestAlwaysAuthorization]zuerst.

Aber selbst wenn Sie eine der oben genannten Methoden implementieren, wird der Benutzer nur dann dazu aufgefordert, wenn in der info.plist ein Eintrag für NSLocationAlwaysUsageDescriptionoder vorhanden ist NSLocationWhenInUseUsageDescription.

Fügen Sie Ihrer info.plist die folgenden Zeilen hinzu, wobei die Zeichenfolgenwerte den Grund darstellen, warum Sie auf den Speicherort des Benutzers zugreifen müssen

<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>

Ich denke, diese Einträge fehlen möglicherweise, seit ich dieses Projekt in Xcode 5 gestartet habe. Ich vermute, Xcode 6 fügt möglicherweise Standardeinträge für diese Schlüssel hinzu, wurde jedoch nicht bestätigt.

Weitere Informationen zu diesen beiden Einstellungen finden Sie hier


13
xcode 6 fügt diese Schlüssel standardmäßig nicht hinzu. Wenn Sie CLLocationManager implementieren möchten, müssen Sie sie manuell hinzufügen
Wesley Smith

1
Ich musste diese auch manuell hinzufügen, konnte nicht über die RawValues-Ansicht von info.plist in Xcode6 hinzufügen!
Kendall Helmstetter Gelner

1
Ich habe für immer danach gesucht. Meine Nachricht [CLLLocationManager authorisationStatus] gab nur den Wert <nil> zurück. Nach dem Hinzufügen der obigen Schlüssel wurden die entsprechenden Aufzählungen für die Nachrichtenausgabe zurückgegeben. Nach dem, was ich herausgefunden habe, ist dies ein bekannter iOS 8-Fehler, konnte aber seit Ewigkeiten nichts in meinem Kontext finden. Danke mil!
MrOli3000

4
Ich mag den String-Wert, den Sie eingegeben haben
Chris Chen

1
Die Nachricht wird als Teilnachricht in der Warnung angezeigt, in der gefragt wird, ob der Benutzer seinen Standort freigeben möchte. Daher scheint es in meiner Bewerbung am sinnvollsten zu sein, einfach leer zu sein. Eine Erklärung, warum Sie den Standort verwenden möchten, ist ebenfalls sinnvoll. NSLocationWhenInUseUsageDescription hat sich jedoch nicht wie erwartet für mich verhalten (dh die Berechtigung wurde immer wieder verweigert, obwohl der Rückgabewert korrekt war). NSLocationAlwaysUsageDescription hat gut funktioniert.
Arcady Bob

104

Um sicherzustellen, dass dies abwärtskompatibel mit iOS 7 ist, sollten Sie überprüfen, ob der Benutzer iOS 8 oder iOS 7 ausführt. Beispiel:

#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

//In ViewDidLoad
if(IS_OS_8_OR_LATER) {
   [self.locationManager requestAlwaysAuthorization];
}

[self.locationManager startUpdatingLocation];

164
Ein besserer Weg als die Version zu überprüfen ist zu überprüfen, ob das Objekt diesen Selektor hat, zB: if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { ...
Programm

1
Ich hatte Probleme, nur die Lösung von @progrmr zu implementieren, als ich auf Xcode 5 aufbaute, da es nicht weiß, was die requestAlwaysAuthorizationMethode ist. Meine zusätzliche Lösung bestand darin, diese Zeile in der ifAnweisung anstelle eines normalen Methodenaufrufs zu verwenden : [self.locationManager performSelector:@selector(requestAlwaysAuthorization)];. Vielleicht ist das für andere offensichtlich, aber ich habe eine Weile gebraucht, um es herauszufinden. Ich denke, es ist die richtige Lösung, bis der endgültige Xcode 6 veröffentlicht wird.
VinceFior

2
Die richtige Lösung besteht darin, mit Xcode 6 zu erstellen. Wenn Sie mit Xcode 5 erstellen, müssen Sie keine Autorisierung anfordern, dies erfolgt automatisch.
Programm

Sie könnten einen Punkt haben. Ich befürchtete, dass mein Code in Xcode 5 kompiliert werden soll (obwohl er unter iOS 8 nur funktioniert, wenn er in Xcode 6 kompiliert wird), während mein Team auf Xcode 6 übergeht. Aber vielleicht ist es ein besserer Workflow, den Code normal und zu schreiben erst zusammenführen, wenn wir zu Xcode 6 wechseln. Danke.
VinceFior

@VinceFior der empfohlene Ansatz ist das bedingte Kompilieren mit dem SDK-definierten Makro __IPHONE_OS_VERSION_MAX_ALLOWED( #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)
Steven Kramer

50
- (void)startLocationManager
{
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    [locationManager startUpdatingLocation];
    [locationManager requestWhenInUseAuthorization]; // Add This Line


}

Und zu Ihrer info.plist Datei Geben Sie hier die Bildbeschreibung ein


1
Eine ähnliche Lösung wurde unter datacalculation.blogspot.in/2014/11/…
iOS-Test

2
@Hemang: Laut Apple Dev-Dokumentation: Es ist sicher, Ortungsdienste zu starten, bevor der Autorisierungsstatus Ihrer App ermittelt wird. Obwohl Sie Standortdienste starten können, liefern diese Dienste keine Daten, bis sich der Autorisierungsstatus in kCLAuthorizationStatusAuthorizedAlways oder kCLAuthorizationStatusAuthorizedWhenInUse ändert.
Andrew

Ein bisschen spät, aber ich empfehle Ihnen, irrelevante Teile Ihrer Plist-Datei zu verbergen, insbesondere FacebookAppID
Przemysław Wrzesiński

Danke Aber das ist nur ein Dummy-Beispiel :)
Neo D1

Es ist auch wichtig, dass das Projekt auf die richtige info.plist zeigt (die, in der der Schlüssel definiert ist). Dies wird in den Projekterstellungseinstellungen unter Info.plist-Datei festgelegt.
klares Licht

30

Laut den Apple-Dokumenten:

Ab iOS 8 ist das Vorhandensein eines NSLocationWhenInUseUsageDescriptionoder eines NSLocationAlwaysUsageDescriptionSchlüsselwerts in der Info.plist-Datei Ihrer App erforderlich. Es ist dann auch erforderlich, die Erlaubnis des Benutzers anzufordern, bevor Sie sich für Standortaktualisierungen registrieren, entweder telefonisch [self.myLocationManager requestWhenInUseAuthorization]oder [self.myLocationManager requestAlwaysAuthorization]je nach Bedarf. Die Zeichenfolge, die Sie in die Info.plist eingegeben haben, wird dann im folgenden Dialogfeld angezeigt.

Wenn der Benutzer die Berechtigung erteilt, läuft es wie gewohnt. Wenn sie die Berechtigung verweigern, wird der Delegat nicht über Standortaktualisierungen informiert.


Ich fand eine einfache Beschreibung hier bei datacalculation.blogspot.in/2014/11/…
iOS Test

28
- (void)viewDidLoad
{

    [super viewDidLoad];
    self.locationManager = [[CLLocationManager alloc] init];

    self.locationManager.delegate = self;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){
        NSUInteger code = [CLLocationManager authorizationStatus];
        if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
            // choose one request according to your business.
            if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
                [self.locationManager requestAlwaysAuthorization];
            } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
                [self.locationManager  requestWhenInUseAuthorization];
            } else {
                NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
            }
        }
    }
    [self.locationManager startUpdatingLocation];
}

>  #pragma mark - CLLocationManagerDelegate

    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
    {
        NSLog(@"didFailWithError: %@", error);
        UIAlertView *errorAlert = [[UIAlertView alloc]
                                   initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [errorAlert show];
    }

    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
        NSLog(@"didUpdateToLocation: %@", newLocation);
        CLLocation *currentLocation = newLocation;

        if (currentLocation != nil) {
            longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
            latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
        }
    }

In iOS 8 müssen Sie zwei zusätzliche Dinge tun, damit der Standort funktioniert: Fügen Sie Ihrer Info.plist einen Schlüssel hinzu und fordern Sie vom Standortmanager eine Autorisierung an, um den Start zu starten. Es gibt zwei Info.plist-Schlüssel für die neue Standortberechtigung. Einer oder beide dieser Schlüssel sind erforderlich. Wenn keiner der Schlüssel vorhanden ist, können Sie startUpdatingLocation aufrufen, der Standortmanager wird jedoch nicht gestartet. Es wird auch keine Fehlermeldung an den Delegaten gesendet (da es nie gestartet wurde, kann es nicht fehlschlagen). Es schlägt auch fehl, wenn Sie einen oder beide Schlüssel hinzufügen, aber vergessen, die Autorisierung explizit anzufordern. Als erstes müssen Sie Ihrer Info.plist-Datei einen oder beide der folgenden Schlüssel hinzufügen:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

Beide Schlüssel haben eine Zeichenfolge

Dies ist eine Beschreibung, warum Sie Ortungsdienste benötigen. Sie können eine Zeichenfolge wie "Standort ist erforderlich, um herauszufinden, wo Sie sich befinden" eingeben, die wie in iOS 7 in der Datei InfoPlist.strings lokalisiert werden kann.

Geben Sie hier die Bildbeschreibung ein


19

Meine Lösung, die in Xcode 5 kompiliert werden kann:

#ifdef __IPHONE_8_0
    NSUInteger code = [CLLocationManager authorizationStatus];
    if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
        // choose one request according to your business.
        if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
            [self.locationManager requestAlwaysAuthorization];
        } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
            [self.locationManager  requestWhenInUseAuthorization];
        } else {
            NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
        }
    }
#endif
    [self.locationManager startUpdatingLocation];

2
Schöne dynamische Lösung, die in allen Apps verwendet werden kann. Ich würde jedoch die Reihenfolge ändern und anstatt nach iPhone 8.0 zu suchen, würde ich prüfen, ob der Standortmanager auf die Autorisierung reagiert, und dann den Autorisierungsstatus ausführen, um den Code zu erhalten. Dies wird es universeller machen.
Zirinisp

Arbeitete auch an xCode 7.2.
Totoro

17

Der alte Code zum Abfragen des Standorts funktioniert in iOS 8 nicht. Sie können diese Methode zur Standortautorisierung ausprobieren:

- (void)requestAlwaysAuthorization
{
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];

    // If the status is denied or only granted for when in use, display an alert
    if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status ==        kCLAuthorizationStatusDenied) {
        NSString *title;
        title = (status == kCLAuthorizationStatusDenied) ? @"Location services are off" :   @"Background location is not enabled";
        NSString *message = @"To use background location you must turn on 'Always' in the Location Services Settings";

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
                                                            message:message
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];
        [alertView show];
    }
    // The user has not enabled any location services. Request background authorization.
    else if (status == kCLAuthorizationStatusNotDetermined) {
        [self.locationManager requestAlwaysAuthorization];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        // Send the user to the Settings for this app
        NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:settingsURL];
    }
}

UIAlertView ist veraltet. Sie sollten stattdessen UIAlertController verwenden.
Pasan Premaratne

Ja, ich weiß, es ist veraltet, aber das wird auch funktionieren. aber ja besser UIAlertController für IOS8 verwenden.
Nits007ak

12

In iOS 8 müssen Sie zwei zusätzliche Dinge tun, damit der Standort funktioniert: Fügen Sie einen Schlüssel zu Ihrer Info.plist hinzu und fordern Sie vom Standortmanager eine Autorisierung an, um den Start zu starten

info.plist:

<key>NSLocationUsageDescription</key>
<string>I need location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>I need location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>I need location</string>

Fügen Sie dies Ihrem Code hinzu

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

1
Es ist nicht klar, ob Ihr Pseudocode ein Präprozessoranruf oder ein regulärer Anruf ist
El Dude

1
Fügen Sie dies Ihrer constants.h- oder .pch-Datei hinzu: #define IS_OS_8_OR_LATER ([[UIDevice currentDevice] .systemVersion floatValue]> = 8.0)
OxenBoxen

Warum sollten Sie beide anfordern, sollten Sie einen Kommentar hinzufügen, in dem nur erwähnt wird, dass je nach Anwendungsbedarf der eine oder andere verwendet werden soll
powerj1984

Der Teil info.plist ist in Unity3d einfach genug, aber wie würde ich den Codeteil hinzufügen, wenn ich Unity3d verwende? wo ?
CthulhuJon

11

Ein häufiger Fehler für Swift-Entwickler:

Stellen Sie zunächst sicher, dass Sie der Liste einen Wert für entweder NSLocationWhenInUseUsageDescriptionoder hinzufügen NSLocationAlwaysUsageDescription.

Wenn immer noch kein Fenster angezeigt wird, in dem Sie um Autorisierung gebeten werden, prüfen Sie, ob Sie die Zeile var locationManager = CLLocationManager()in die viewDidLoadMethode Ihres View Controllers einfügen. Wenn Sie dies tun, wird auch dann locationManager.requestWhenInUseAuthorization()nichts angezeigt, wenn Sie anrufen . Dies liegt daran, dass nach der Ausführung von viewDidLoad die Variable locationManager freigegeben (gelöscht) wird.

Die Lösung besteht darin, die Zeile var locationManager = CLLocationManager()oben in der Klassenmethode zu platzieren.


9

Vor [locationManager startUpdatingLocation];, fügen Anfrage eine iOS8 Ortungsdienste:

if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
    [locationManager requestAlwaysAuthorization];

Bearbeiten Sie die App Info.plistund fügen Sie den Schlüssel NSLocationAlwaysUsageDescriptionmit dem Zeichenfolgenwert hinzu, der dem Benutzer angezeigt wird (z. B. We do our best to preserve your battery life.).

Wenn Ihre App nur bei geöffnetem App Ortungsdienste benötigt, ersetzen Sie:

requestAlwaysAuthorizationmit requestWhenInUseAuthorizationund

NSLocationAlwaysUsageDescriptionmit NSLocationWhenInUseUsageDescription.


9

Ich habe an einer App gearbeitet, die auf iOS 8 aktualisiert wurde, und die Ortungsdienste funktionierten nicht mehr. Sie werden wahrscheinlich einen Fehler im Debug-Bereich bekommen, wie folgt:

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.

Ich habe das am wenigsten aufdringliche Verfahren durchgeführt. NSLocationAlwaysUsageDescriptionFügen Sie zuerst einen Eintrag zu Ihrer info.plist hinzu:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass ich den Wert für diesen Schlüssel nicht ausgefüllt habe. Dies funktioniert immer noch und ich bin nicht besorgt, da dies eine Inhouse-App ist. Außerdem gibt es bereits einen Titel, in dem nach Standortdiensten gefragt wird, sodass ich nichts Redundantes tun wollte.

Als nächstes habe ich eine Bedingung für iOS 8 erstellt:

if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    [_locationManager requestAlwaysAuthorization];
}

Danach wird die locationManager:didChangeAuthorizationStatus:Methode aufgerufen:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:  (CLAuthorizationStatus)status
{
    [self gotoCurrenLocation];
}

Und jetzt funktioniert alles gut. Lesen Sie wie immer die Dokumentation .


7

Lösung mit Abwärtskompatibilität:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
    [self.locationManager respondsToSelector:requestSelector]) {
    [self.locationManager performSelector:requestSelector withObject:NULL];
} else {
    [self.locationManager startUpdatingLocation];
}

Richten Sie den NSLocationWhenInUseUsageDescription-Schlüssel in Ihrer Info.plist ein


2
Dies ist nicht korrekt. Was ist mit dem Fall kCLAuthorizationStatusDenied? es springt zu else und aktualisiert den Ort, der nicht korrekt ist!
Electronix384128

@ BenMarten Ich denke nicht, dass es wichtig sein sollte. Sie sollten das selbst erledigen locationManager: (CLLocationManager *)manager didFailWithError: (NSError *)error. Er hat jedoch vergessen, startUpdatingLocation zur if-Anweisung hinzuzufügen. Nachdem sie diese akzeptiert oder abgelehnt hat, wird startUpdateLocation nicht aufgerufen.
Chris

6

Lösung mit Abwärtskompatibilität, die keine Xcode-Warnungen erzeugt:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
  [self.locationManager respondsToSelector:requestSelector]) {
((void (*)(id, SEL))[self.locationManager methodForSelector:requestSelector])(self.locationManager, requestSelector);
  [self.locationManager startUpdatingLocation];
} else {
  [self.locationManager startUpdatingLocation];
}

Setup- NSLocationWhenInUseUsageDescriptionTaste in Ihrem Info.plist.

Für iOS Version 11.0+ : Setup- NSLocationAlwaysAndWhenInUseUsageDescriptionSchlüssel in Ihrem Info.plist. zusammen mit anderen 2 Schlüsseln.


Dies ist nicht korrekt. Was ist mit dem Fall kCLAuthorizationStatusDenied? es springt zu else und aktualisiert den Ort, der nicht korrekt ist!
Electronix384128

Das ist ziemlich seltsam, das funktioniert gut für mich, nicht gut, perfekt, sowohl zulassen als auch nicht zulassen. Selbst die Jacob-Lösung sieht genau aus, hat aber bei mir nicht funktioniert. Seltsam, aber funktioniert !!!
Josh

Das Aufrufen von [self.locationManager startUpdatingLocation] direkt nach requestWhenInUseAuthorization hat keinen Sinn
Kostia Kim

5

Dies ist ein Problem mit ios 8 Fügen Sie dies Ihrem Code hinzu

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

und zu info.plist:

 <key>NSLocationUsageDescription</key>
 <string>I need location</string>
 <key>NSLocationAlwaysUsageDescription</key>
 <string>I need location</string>
 <key>NSLocationWhenInUseUsageDescription</key>
 <string>I need location</string>

NSLocationUsageDescriptionwird nicht auf iOS8 + verwendet
Carlos Ricardo

4

Um in iOS 8 auf den Benutzerstandort zuzugreifen, müssen Sie Folgendes hinzufügen:

NSLocationAlwaysUsageDescription in the Info.plist 

Dadurch wird der Benutzer um die Erlaubnis gebeten, seinen aktuellen Standort abzurufen.


4

Ziel-C-Verfahren Befolgen Sie die folgenden Anweisungen:

Für iOS-11 Für iOS 11 sehen Sie sich diese Antwort an: iOS 11-Standortzugriff

Sie müssen zwei Schlüssel zur Liste hinzufügen und die folgende Meldung anzeigen:

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

Geben Sie hier die Bildbeschreibung ein Für iOS-10 und niedriger:

NSLocationWhenInUseUsageDescription

Geben Sie hier die Bildbeschreibung ein

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
    [locationManager requestWhenInUseAuthorization];
}else{
    [locationManager startUpdatingLocation];
} 

Methoden delegieren

#pragma mark - Lolcation Update 
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
    UIAlertView *errorAlert = [[UIAlertView alloc]
                               initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
        case kCLAuthorizationStatusRestricted:
        case kCLAuthorizationStatusDenied:
        {
            // do some error handling
        }
            break;
        default:{
            [locationManager startUpdatingLocation];
        }
            break;
    }
}
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations lastObject];
    userLatitude =  [NSString stringWithFormat:@"%f", location.coordinate.latitude] ;
    userLongitude =  [NSString stringWithFormat:@"%f",location.coordinate.longitude];
    [locationManager stopUpdatingLocation];
}

Schnelle Vorgehensweise

Befolgen Sie die folgenden Anweisungen:

Für iOS-11 Für iOS 11 sehen Sie sich diese Antwort an: iOS 11-Standortzugriff

Sie müssen zwei Schlüssel zur Liste hinzufügen und die folgende Meldung anzeigen:

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

Geben Sie hier die Bildbeschreibung ein Für iOS-10 und niedriger:

Geben Sie hier die Bildbeschreibung ein

import CoreLocation
class ViewController: UIViewController ,CLLocationManagerDelegate {
var locationManager = CLLocationManager()

//MARK- Update Location 
func updateMyLocation(){
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
    if locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)){
       locationManager.requestWhenInUseAuthorization()
    }
    else{
        locationManager.startUpdatingLocation()
    }
}

Methoden delegieren

//MARK: Location Update
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
    NSLog("Error to update location :%@",error)
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    switch status {
    case .NotDetermined: break
    case .Restricted: break
    case .Denied:
            NSLog("do some error handling")
        break
    default:
        locationManager.startUpdatingLocation()
    }
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
     let location = locations.last! as CLLocation
    var latitude = location.coordinate.latitude
    var longitude = location.coordinate.longitude

}

Stellen Sie sicher, dass auch NSLocationAlwaysUsageDescription hinzugefügt wird. Andernfalls wird beim Hochladen im App Store eine Fehlermeldung angezeigt.
Alok

Ihre Nachricht sollte auch informativ sein, da sonst Apple die App während des Wiederholungsprozesses ablehnt.
Alok

3

Für diejenigen, die Xamarin verwenden , musste ich den Schlüssel NSLocationWhenInUseUsageDescriptionmanuell zur info.plist hinzufügen, da er weder in Xamarin 5.5.3 Build 6 noch in XCode 6.1 in den Dropdown-Listen verfügbar war - nur NSLocationUsageDescriptionin der Liste, und das führte dazu, dass der CLLocationManagerfortfuhr scheitern lautlos.


2
        // ** Don't forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string

        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        // Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
        if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
            [self.locationManager requestWhenInUseAuthorization];
        }
        [self.locationManager startUpdatingLocation];


    // Location Manager Delegate Methods    
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        NSLog(@"%@", [locations lastObject]);

}

2

Ein kleiner Helfer für alle, die mehr als eine Info.plist-Datei haben ...

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Add NSLocationWhenInUseUsageDescription string' {} 

Das erforderliche Tag wird allen Info.plist-Dateien im aktuellen Verzeichnis (und den Unterordnern) hinzugefügt.

Ein anderer ist:

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Set NSLocationWhenInUseUsageDescription $YOURDESCRIPTION' {} 

Es wird Ihre Beschreibung zu allen Dateien hinzufügen.



2

In iOS9 (bei Verwendung von Xcode 7 und Swift 2) wird ein ähnlicher Fehler angezeigt: Der Versuch, MapKit-Standortaktualisierungen zu starten, ohne zur Standortautorisierung aufzufordern. Muss zuerst - [CLLocationManager requestWhenInUseAuthorization] oder - [CLLocationManager requestAlwaysAuthorization] aufrufen. Ich habe ein Tutorial verfolgt, aber der Tutor hat iOS8 und Swift 1.2 verwendet. Es gibt einige Änderungen in Xcode 7 und Swift 2, ich habe diesen Code gefunden und er funktioniert gut für mich (wenn jemand Hilfe benötigt):

import UIKit
import MapKit
import CoreLocation

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    // MARK: Properties
    @IBOutlet weak var mapView: MKMapView!

    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
        self.mapView.showsUserLocation = true

    }

    // MARK: - Location Delegate Methods

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.last
        let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
        self.mapView.setRegion(region, animated: true)
    }

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print("Errors: " + error.localizedDescription)
    }
}

Schließlich habe ich das in info.plist eingefügt: Informationseigenschaftsliste: NSLocationWhenInUseUsageDescription Wert: App benötigt Standortserver für Mitarbeiter


2

Um auf den Benutzerstandort in iOS zuzugreifen. Sie müssen zwei Schlüssel hinzufügen

NSLocationWhenInUseUsageDescription

NSLocationAlwaysUsageDescription

in die Datei Info.plist.

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Because I want to know where you are!</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Want to know where you are!</string>

Siehe dieses Bild unten.

Info.plist Bild


1
  1. Fügen Sie einen Schlüssel NSLocationWhenInUseUsageDescriptionoder NSLocationAlwaysUsageDescription(Hintergrund-GPS-Verwendung) mit einer Zeichenfolge hinzu, in der Sie aufgefordert werden, für info.plistjedes Ziel GPS zu verwenden .

  2. Bitten Sie um Erlaubnis, indem Sie Folgendes ausführen:

    [self initLocationManager: locationManager];

Wo initLocationManagerist:

// asks for GPS authorization on iOS 8
-(void) initLocationManager:(CLLocationManager *) locationManager{

    locationManager = [[CLLocationManager alloc]init];

    if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
        [locationManager requestAlwaysAuthorization];
}

Denken Sie daran, dass info.plistdie App den Benutzer nicht fragt , wenn die Schlüssel nicht für jedes Ziel vorhanden sind. Das ifbietet Kompatibilität mit iOS 7 und die respondsToSelector:Methode garantiert zukünftige Kompatibilität, anstatt nur das Problem für iOS 7 und 8 zu lösen.


0

Das Problem für mich war, dass die Klasse, die die CLLocationManagerDelegatewar, privat war, was verhinderte, dass alle Delegatenmethoden aufgerufen wurden. Ich denke, es ist keine sehr häufige Situation, aber ich dachte, ich würde es erwähnen, falls es niemandem hilft.


0

Ich füge Sie diesen Schlüssel in InfoPlist.stringsin iOS 8.4, iPad mini 2. Es funktioniert auch. Ich setze keinen Schlüssel NSLocationWhenInUseUsageDescriptionin meine Info.plist.


InfoPlist.strings :

"NSLocationWhenInUseUsageDescription" = "I need GPS information....";

Basis auf diesem Thread , hieß es as in iOS 7, kann in der InfoPlist.strings lokalisiert werden. In meinem Test können diese Schlüssel direkt in der Datei konfiguriert werden InfoPlist.strings.

Als erstes müssen Sie Ihrer Info.plist-Datei einen oder beide der folgenden> Schlüssel hinzufügen:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

Diese beiden Schlüssel haben eine Zeichenfolge, die beschreibt, warum Sie Ortungsdienste benötigen. Sie können eine Zeichenfolge wie "Standort ist erforderlich, um herauszufinden, wo Sie sich befinden" eingeben , die wie in iOS 7 in der Datei InfoPlist.strings lokalisiert werden kann.


AKTUALISIEREN:

Ich denke @IOS, die Methode ist besser. Fügen Sie den Schlüssel Info.plistmit leerem Wert hinzu und fügen Sie lokalisierte Zeichenfolgen hinzu InfoPlist.strings.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.