La finestra di dialogo di autorizzazione della posizione corrente scompare troppo rapidamente


175

La mia app prende la posizione dell'utente, ottiene le coordinate e fornisce una distanza da o verso la loro destinazione o origine. Tutte queste possibili destinazioni sono mostrate in una vista tabella, quindi ottengo le coordinate degli utenti contemporaneamente al popolamento della tabella. L'unica cosa è che la vista di avviso che richiede la posizione degli utenti appare quindi scompare così rapidamente che è impossibile fare clic su di essa!

Esiste un modo per presentare manualmente questo avviso al primo caricamento dell'app? Ho provato a ottenere la posizione dell'utente quando l'app si carica per provare a forzare la visualizzazione dell'avviso, ma non ha funzionato.

Risposte:


700

Sebbene difficile da rintracciare, la soluzione per questo è abbastanza semplice.

Attraverso molte prove ed errori ho scoperto che mentre la finestra di dialogo di accesso alla posizione viene visualizzata quando si tenta di accedere a tutti i servizi di posizione nell'app per la prima volta, la finestra di dialogo scompare da sola (senza alcuna interazione dell'utente) se l' CLLocationManageroggetto viene rilasciato prima l'utente risponde alla finestra di dialogo.

Stavo creando CLLocationManagerun'istanza nel mio viewDidLoadmetodo. Poiché si trattava di un'istanza locale del metodo, l'istanza è stata rilasciata da ARC dopo che il metodo ha completato l'esecuzione. Non appena l'istanza è stata rilasciata, la finestra di dialogo è scomparsa. La soluzione era piuttosto semplice. Modificare l' CLLocationManageristanza da una variabile a livello di metodo in una variabile di istanza a livello di classe. Ora l' CLLocationManageristanza viene rilasciata solo dopo aver scaricato la classe.


117
Vorrei poter dare 100
coder

1
Ho appena riscontrato lo stesso problema con Xamarin.iOS. Rendi l'ambito della classe CLLocationManager e la finestra di dialogo rimane visibile.
Krumelur,

1
Yaaaaa .... se potessi andare avanti e darti un rilancio, sarebbe greeeeeaaaat. (Seriamente, questo è un grosso risparmio anche per me)
Garfonzo,

2
Devo unirmi anche a questa festa. Ecco, ricevi da me un Internet High Five!
Matthieu Riegler,

3
Chiunque abbia questo problema in Swift si assicuri di spostare la dichiarazione di LocationManager fuori da viewDidLoad. Saluti!
KD.

5

Stesso sintomo, causa diversa: non chiamare startUpdatingLocationpiù di una volta di fila .

Avevo strutturato accidentalmente cose in modo tale che il codice chiamasse involontariamente startUpdatingLocationdue volte di seguito, il che è apparentemente negativo. Potrebbe anche aver avuto a che fare con la scelta della coda da quando stavo aspettando di iniziare l'aggiornamento in attesa del risultato di una richiesta di rete, ma non avevo bisogno di fare nessuna magia GCD per risolverlo ... avevo solo bisogno di assicurarmi non ha ripetuto l'inizio.

Spero che qualcuno sia in grado di beneficiare del mio dolore. :)


5

Ho affrontato una situazione simile. Dopo il debug ho trovato

let locationManager = CLLocationManager()

viene chiamato nell'ambito di un metodo, ma dovrebbe essere chiamato a livello globale.

Perché?

In breve, locationManager è stato rilasciato dopo la restituzione del metodo. Ma non dovrebbe essere rilasciato fino a quando l'utente non dà o nega l'autorizzazione


4

Cado nello stesso problema (almeno dai sintomi). Nel mio caso il problema era nel - (void)applicationWillResignActive:(UIApplication *)application;metodo, in cui stavo rilasciando la mia CLLocationManageristanza come parte della preparazione per la transizione in background. Quando l'ho rimosso e lasciato solo nel - (void)applicationDidEnterBackground:(UIApplication *)application;problema è sparito.
La parte difficile è che l'avviso di posizione principale sospende l'applicazione mentre è ancora in primo piano.
Spero che ti possa aiutare, mi ci è voluto molto tempo per trovare quel bastardo :)


4

So che questa è una risposta molto tardi. Ma può aiutare qualcuno. Ho anche affrontato lo stesso problema e ho impiegato un'ora per identificarlo. All'inizio il mio codice era così.

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

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

    [locationManager release];

Ora l'avviso di posizione è scomparso rapidamente. Quando rimuovo il commento sull'ultima riga funziona correttamente.

   // [locationManager release];

3
Questo è vero. L'unica avvertenza che aggiungerei a questa risposta è che quando il tuo progetto ha ARC abilitato, non è necessario includere la dichiarazione di rilascio nel codice e continuerai a riscontrare questo problema. L'unico modo per risolvere il problema in quello scenario è rendere la variabile a livello di classe anziché a livello di metodo.
Zoli,

3

Ho riscontrato anche questo problema, ma la soluzione nel mio caso si è rivelata completamente diversa dalla risposta accettata.

Nella mia app, mi stava chiamando stopUpdatingLocationda applicationWillResignActive. Questo era un problema perché applicationWillResignActiveviene chiamato quando viene visualizzata la finestra di dialogo delle autorizzazioni. Ciò stava causando stopUpdatingLocationimmediatamente dopo startUpdatingLocation, motivo per cui la finestra di dialogo sarebbe scomparsa immediatamente.

La soluzione era semplicemente alla chiamata stopUpdatingLocationdal applicationDidEnterBackgroundposto.


2

Mi stava succedendo mentre usavo il simulatore iOS. Ho determinato che si stava verificando perché il mio Schema di esecuzione simulava una posizione. Penso che questo abbia lo stesso effetto di una chiamata locationManager.startUpdatingLocation()al lancio e quindi stava chiudendo la finestra di dialogo.

Deselezionando la casella di controllo "Consenti simulazione posizione" nella finestra di dialogo Modifica schemi, il problema è stato risolto. Una volta che funziona come desiderato e l'autorizzazione è impostata, è possibile riattivare la simulazione della posizione e il simulatore funzionerà correttamente da quel momento in poi.


Questo ha funzionato in qualche misura per me. Almeno ho avuto modo di vedere il dialogo
CppChase

2

Swift 4 e iOS 11 :

Assicurati di aver aggiunto linee di privacy (sia sempre che quandoInUse ) al tuo .plistfile e aggiungi CoreLocationFramework al tuo progetto

La finestra di dialogo di autorizzazione della posizione appare correttamente quando ho cambiato:

locationManager.requestAlwaysAuthorization()

con:

locationManager.requestWhenInUseAuthorization()

PS .: Ho provato TUTTI i consigli e tutto fallisce (richiedere l'autorizzazione a viewDidLoad, varanziché letper locationManager, non iniziare startUpdatingLocation()dopo la richiesta ... Penso che sia un bug e spero che lo risolveranno al più presto ..


Ho seguito anche tutti i consigli, ma ho sempre lo stesso problema. Viene visualizzata brevemente la finestra di dialogo di autorizzazione della posizione, quindi scompare immediatamente. Quindi viene visualizzata la mia autorizzazione per la finestra di dialogo di notifica (questa è normale), quando premo accetta o rifiuta, viene visualizzata un'altra autorizzazione per la posizione (questa volta rimane e lasciami accettare o rifiutare).

@BitoQ Sì, anche per me. Stessa situazione ma almeno possiamo vedere questa finestra di dialogo, spero che con il prossimo iOS 11.1 correggano questo bug ..
Alessandro Ornano,

1

La soluzione SWIFT 4 @Zoli sarà simile a:

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

0

la maggior parte si definisce variabile locationManager come oggetto globale.

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

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

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

0

Ho incontrato la tua stessa situazione.

  • La mia soluzione è stata cambiata da variabile locale a istanza membro.
  • La causa era che l'istanza local? Non era valida dopo che il metodo era terminato che include il locale la variabile (di extendere il mio locationManager)
  • Mio ambiente: Xcode9.3.1
#importare 
@interface ViewController ()

@fine

@implementation ViewController
@synthesize locManager; // dopo
- (vuoto) viewDidLoad {
    [super viewDidLoad];
    // Effettua qualsiasi configurazione aggiuntiva dopo aver caricato la vista, in genere da un pennino.

    // MyLocationService * locManager = [[BSNLocationService alloc] init: nil]; // prima. la loc. il delegato non ha funzionato perché l'istanza è diventata non valida dopo questo metodo.
    self-> locManager = [[MyLocationService alloc] init: nil]; // dopo
    locManager.startService;
}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.