Der aktuelle Standortberechtigungsdialog verschwindet zu schnell

175

Meine App ermittelt den Standort des Benutzers, ermittelt die Koordinaten und gibt eine Entfernung zu oder von seinem Ziel oder Ursprung an. Alle diese möglichen Ziele werden in einer Tabellenansicht angezeigt, sodass ich die Benutzerkoordinaten gleichzeitig mit dem Auffüllen der Tabelle erhalte. Das einzige ist, dass die Warnansicht, die nach dem Standort des Benutzers fragt, so schnell verschwindet, dass es unmöglich ist, darauf zu klicken!

Gibt es eine Möglichkeit, diese Warnung beim ersten Laden der App manuell anzuzeigen? Ich habe versucht, den Standort des Benutzers zu ermitteln, wenn die App geladen wird, um zu versuchen, die Anzeige der Warnung zu erzwingen, aber das hat nicht funktioniert.

Glenn Sayers
quelle

Antworten:

696

Die Lösung hierfür ist zwar schwer zu finden, aber recht einfach.

Durch viele Versuche und Irrtümer habe ich herausgefunden, dass das Dialogfeld "Standortzugriff" angezeigt wird, wenn Sie zum ersten Mal versuchen, auf Standortdienste in der App zuzugreifen. Das Dialogfeld verschwindet jedoch von selbst (ohne Benutzerinteraktion), wenn das CLLocationManagerObjekt zuvor freigegeben wurde Der Benutzer antwortet auf den Dialog.

Ich habe eine CLLocationManagerInstanz in meiner viewDidLoadMethode erstellt. Da dies eine lokale Instanz der Methode war, wurde die Instanz von ARC freigegeben, nachdem die Ausführung der Methode abgeschlossen war. Sobald die Instanz freigegeben wurde, verschwand der Dialog. Die Lösung war ziemlich einfach. Ändern Sie die CLLocationManagerInstanz von einer Variablen auf Methodenebene in eine Instanzvariable auf Klassenebene. Jetzt wird die CLLocationManagerInstanz erst freigegeben, wenn die Klasse entladen ist.

Zoli
quelle
117
Ich wünschte, ich könnte Ihnen +100
Codierer
1
Treffen Sie einfach das gleiche Problem mit Xamarin.iOS. Machen Sie den CLLocationManager-Klassenbereich und der Dialog bleibt sichtbar.
Krumelur
1
Yaaaaa ... wenn du weitermachen und dir eine Gehaltserhöhung geben könntest, wäre das greeeeeaaaat. (Im Ernst, das ist auch eine große Rettung für mich)
Garfonzo
2
Ich muss mich auch dieser Party anschließen. Hier, hol dir ein Internet High Five von mir!
Matthieu Riegler
3
Wenn Sie dieses Problem in Swift haben, stellen Sie sicher, dass Sie die Deklaration von LocationManager außerhalb von viewDidLoad verschieben. Prost!
KD.
5

Gleiches Symptom, andere Ursache: Nicht startUpdatingLocationmehr als einmal hintereinander anrufen .

Ich hatte versehentlich Dinge so strukturiert, dass der Code ungewollt startUpdatingLocationzweimal hintereinander aufgerufen wurde, was anscheinend schlecht ist. Es könnte auch etwas mit der Auswahl der Warteschlange zu tun haben, da ich darauf gewartet habe, mit dem Update zu beginnen, bis das Ergebnis einer Netzwerkanforderung vorliegt, aber ich musste keine GCD-Magie ausführen, um das Problem zu beheben. Ich musste nur sicherstellen, dass ich es tat habe den Start nicht wiederholt.

Hoffe, jemand kann von meinen Schmerzen profitieren. :) :)

Clozach
quelle
5

Ich habe die ähnliche Situation konfrontiert. Nach dem Debuggen habe ich gefunden

let locationManager = CLLocationManager()

wird in einem Methodenbereich aufgerufen, sollte jedoch global aufgerufen werden.

Warum?

Kurz gesagt, locationManager wurde freigegeben, nachdem die Methode zurückgegeben wurde. Es sollte jedoch erst freigegeben werden, wenn der Benutzer die Erlaubnis erteilt oder verweigert

Ankur Lahiry
quelle
4

Ich falle in das gleiche Problem (zumindest durch Symptome). In meinem Fall lag das Problem in der - (void)applicationWillResignActive:(UIApplication *)application;Methode, bei der ich meine CLLocationManagerInstanz als Teil der Vorbereitung auf den Hintergrundübergang freigab. Wenn ich es entfernt und nur im - (void)applicationDidEnterBackground:(UIApplication *)application;Problem belassen habe , ist es weg.
Der schwierige Teil ist, dass der Core Location-Alarm Ihre Anwendung aussetzt, während sie sich noch im Vordergrund befindet.
Hoffe, dass es dir helfen wird, ich habe viel Zeit gebraucht, um diesen Bastard zu gründen :)

Ariel
quelle
4

Ich weiß, dass dies eine sehr späte Antwort ist. Aber es kann jemandem helfen. Ich hatte auch das gleiche Problem und verbrachte eine Stunde damit, das Problem zu identifizieren. Zuerst war mein Code so.

CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];

CLLocation *location = locationManager.location;
//my stuff with the location

    [locationManager release];

Jetzt verschwand der Standortalarm schnell. Wenn ich die letzte Zeile auskommentiere, funktioniert sie korrekt.

   // [locationManager release];
Ramaraj T.
quelle
3
Das ist wahr. Die einzige Einschränkung, die ich zu dieser Antwort hinzufügen möchte, ist, dass Sie, wenn für Ihr Projekt ARC aktiviert ist, die Versionsanweisung nicht in Ihren Code aufnehmen müssen und trotzdem auf dieses Problem stoßen. Die einzige Möglichkeit, das Problem in diesem Szenario zu beheben, besteht darin, die Variable auf Klassenebene anstelle von Methodenebene zu erstellen.
Zoli
3

Ich bin auch auf dieses Problem gestoßen, aber die Lösung in meinem Fall stellte sich als völlig anders heraus als die akzeptierte Antwort.

In meiner app, ich rufe stopUpdatingLocationaus applicationWillResignActive. Dies war ein Problem, da applicationWillResignActivees aufgerufen wird, wenn der Berechtigungsdialog angezeigt wird. Dies wurde stopUpdatingLocationunmittelbar danach verursacht startUpdatingLocation, weshalb der Dialog sofort verschwand.

Die Lösung war einfach zu Anruf stopUpdatingLocationaus applicationDidEnterBackgroundstatt.

Alan Kinnaman
quelle
2

Dies passierte mir während der Verwendung des iOS-Simulators. Ich habe festgestellt, dass es aufgetreten ist, weil mein Laufschema einen Ort simuliert hat. Ich denke, dies hat den gleichen Effekt wie das Aufrufen locationManager.startUpdatingLocation()beim Start und so wurde der Dialog geschlossen.

Das Deaktivieren des Kontrollkästchens "Standortsimulation zulassen" im Dialogfeld "Schemas bearbeiten" wurde behoben. Sobald es wie gewünscht funktioniert und die Berechtigung festgelegt ist, können Sie die Standortsimulation wieder aktivieren und der Simulator funktioniert von da an einwandfrei.

Paolo
quelle
Das hat bis zu einem gewissen Grad für mich funktioniert. Zumindest habe ich den Dialog gesehen
CppChase
2

Swift 4 und iOS 11 :

Stellen Sie sicher, dass Sie Ihrer Datei Datenschutzzeilen hinzugefügt haben (sowohl immer als auch bei Verwendung ), .plistund fügen Sie CoreLocationIhrem Projekt Framework hinzu

Das Dialogfeld für die Standortberechtigung wird korrekt angezeigt, wenn ich Folgendes geändert habe:

locationManager.requestAlwaysAuthorization()

mit:

locationManager.requestWhenInUseAuthorization()

PS .: Ich habe ALLE Ratschläge ausprobiert und alle schlagen fehl (Autorisierung anfordern viewDidLoad, varanstatt letfür locationManager, nicht startUpdatingLocation()nach Anfrage zu starten. Ich denke, es ist ein Fehler und ich hoffe, dass sie ihn so schnell wie möglich beheben.

Alessandro Ornano
quelle
Ich habe auch alle Ratschläge befolgt, aber ich habe immer das gleiche Problem. Das Dialogfeld für die Standortberechtigung wird kurz angezeigt und verschwindet dann sofort. Dann wird meine Berechtigung zum Benachrichtigungsdialog angezeigt (diese ist normal). Wenn ich auf Akzeptieren oder Ablehnen drücke, wird eine andere Standortberechtigung angezeigt (diesmal bleibt sie bestehen und ich kann akzeptieren oder ablehnen).
@BitoQ Ja, auch für mich. Gleiche Situation, aber zumindest können wir diesen Dialog sehen, ich hoffe, mit dem nächsten iOS 11.1 werden sie diesen Fehler beheben.
Alessandro Ornano
1

Die SWIFT 4 @ Zoli-Lösung sieht folgendermaßen aus:

class WhateverViewController: UIViewController {
    let locationManager = CLLocationManager() // here is the point of the @Zoli answer

    // some code
    override func viewDidLoad() {
        super.viewDidLoad()

        // some other code
        locationManager.requestWhenInUseAuthorization()
        // some other code
    }
}
wm.p1us
quelle
0

Sie definieren die locationManager-Variable am häufigsten als globales Objekt.

@interface ViewController : UIViewController
{
    CLLocationManager *locationManager;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    [locationManager startUpdatingLocation];
}
Mahdi Nili
quelle
0

Ich habe die gleiche Situation von dir getroffen.

  • Meine Lösung wurde von lokaler Variable in Mitgliedsinstanz geändert.
  • Die Ursache war, dass die lokale Instanz nach Abschluss der Methode ungültig war, die die lokale Variable (zum Erweitern meines locationManager) enthält.
  • Mein Env.: Xcode9.3.1
#importieren 
@interface ViewController ()

@Ende

@implementation ViewController
@synthesize locManager; // nach dem
- (void) viewDidLoad {
    [super viewDidLoad];
    // Führen Sie nach dem Laden der Ansicht zusätzliche Einstellungen durch, normalerweise von einer Schreibfeder.

    // MyLocationService * locManager = [[BSNLocationService alloc] init: nil]; // Vor. die loc. Der Delegat hat nicht funktioniert, da die Instanz nach dieser Methode ungültig wurde.
    self-> locManager = [[MyLocationService alloc] init: nil]; // nach dem
    locManager.startService;
}}

user2058374
quelle