O diálogo de permissão de local atual desaparece muito rapidamente

175

Meu aplicativo pega a localização do usuário, obtém as coordenadas e fornece uma distância de ou para seu destino ou origem. Todos esses destinos possíveis são mostrados em uma exibição de tabela, por isso estou coordenando os usuários ao mesmo tempo em que preenche a tabela. A única coisa é que a exibição de alerta que solicita a localização dos usuários aparece e desaparece tão rapidamente que é impossível clicar nela!

Existe alguma maneira de apresentar este alerta manualmente quando o aplicativo é carregado pela primeira vez? Tentei obter a localização do usuário quando o aplicativo é carregado para tentar forçar a exibição do alerta, mas isso não funcionou.

Glenn Sayers
fonte

Respostas:

698

Embora seja difícil rastrear, a solução para isso é bastante simples.

Através de muitas tentativas e erros, descobri que, embora a caixa de diálogo de acesso ao local seja exibida quando você tenta acessar qualquer serviço de localização no aplicativo pela primeira vez, o diálogo desaparece por si só (sem nenhuma interação do usuário) se o CLLocationManager objeto for liberado antes o usuário responde à caixa de diálogo.

Eu estava criando uma CLLocationManagerinstância no meu viewDidLoadmétodo. Como essa era uma instância local do método, a instância foi liberada pelo ARC após a conclusão da execução do método. Assim que a instância foi lançada, a caixa de diálogo desapareceu. A solução foi bastante simples. Altere a CLLocationManagerinstância de uma variável no nível do método para uma variável da instância no nível da classe. Agora, a CLLocationManagerinstância é liberada apenas quando a classe é descarregada.

Zoli
fonte
117
Eu gostaria de poder dar-lhe +100
coder
1
Apenas acerte o mesmo problema com o Xamarin.iOS. Torne o escopo da classe CLLocationManager e a caixa de diálogo permanecerá visível.
Krumelur 21/07/2014
1
Yaaaaa .... se você pudesse ir em frente e fazer um aumento, isso seria ótimo. (Sério, este é um grande salvar para mim também)
Garfonzo
2
Eu tenho que participar dessa festa também. Aqui, obtenha um Internet High Five de mim!
Matthieu Riegler
3
Qualquer pessoa com esse problema no Swift certifique-se de mover a declaração do LocationManager para fora de viewDidLoad. Felicidades!
KD.
5

Mesmo sintoma, causa diferente: não ligue startUpdatingLocationmais de uma vez seguidas .

Estruturei acidentalmente coisas de tal forma que o código estava involuntariamente chamando startUpdatingLocation duas vezes seguidas, o que é aparentemente ruim. Também poderia ter algo a ver com a escolha da fila, já que eu estava esperando para começar a atualizar enquanto aguardava o resultado de uma solicitação de rede, mas não precisava fazer nenhuma mágica do GCD para corrigi-la ... só precisava ter certeza de que não repetiu o início.

Espero que alguém seja capaz de se beneficiar da minha dor. :)

clozach
fonte
5

Eu enfrentei a situação semelhante. Após a depuração, encontrei

let locationManager = CLLocationManager()

é chamado em um escopo de método, mas deve ser chamado globalmente.

Por quê?

Em poucas palavras, o locationManager foi lançado após o retorno do método. Mas não deve ser liberado até que o usuário dê ou negue permissão

Ankur Lahiry
fonte
4

Caí no mesmo problema (pelo menos por sintomas). No meu caso, o problema estava no - (void)applicationWillResignActive:(UIApplication *)application;método, onde eu estava liberando minha CLLocationManagerinstância como parte da preparação para a transição em segundo plano. Quando eu removi e deixei apenas no - (void)applicationDidEnterBackground:(UIApplication *)application;problema se foi.
A parte complicada é que o alerta de localização principal suspende seu aplicativo enquanto ele ainda está em primeiro plano.
Espero que ajude você, demorei muito tempo para encontrar aquele bastardo :)

Ariel
fonte
4

Eu sei que esta é uma resposta muito tardia. Mas isso pode ajudar alguém. Também enfrentei o mesmo problema e passei uma hora para identificar o problema. No começo, meu código era assim.

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

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

    [locationManager release];

Agora, o alerta de localização desapareceu rapidamente. Quando descomente a última linha, ela está funcionando corretamente.

   // [locationManager release];
Ramaraj T
fonte
3
Isso é verdade. A única ressalva que gostaria de acrescentar a essa resposta é que, quando seu projeto tiver o ARC ativado, você não precisará incluir a declaração de release no seu código e continuará com esse problema. A única maneira de resolver o problema nesse cenário é tornar a variável em nível de classe em vez de em nível de método.
Zoli
3

Também encontrei esse problema, mas a solução no meu caso acabou sendo completamente diferente da resposta aceita.

No meu aplicativo, eu estava ligando stopUpdatingLocationde applicationWillResignActive. Este foi um problema porque applicationWillResignActiveé chamado quando a caixa de diálogo de permissão é exibida. Isso estava causando stopUpdatingLocationimediatamente depois startUpdatingLocation, razão pela qual a caixa de diálogo desapareceu imediatamente.

A solução era simplesmente ligar stopUpdatingLocationde applicationDidEnterBackgroundvez.

Alan Kinnaman
fonte
2

Isso estava acontecendo comigo enquanto usava o iOS Simulator. Eu determinei que isso estava ocorrendo porque meu Esquema de Execução estava simulando um local. Eu acho que isso tem o mesmo efeito que chamar locationManager.startUpdatingLocation()no lançamento e por isso estava fechando a caixa de diálogo.

Desmarcar a caixa de seleção "Permitir simulação de local" na caixa de diálogo Editar esquemas corrigiu o problema. Uma vez que funcione como você deseja e com a permissão definida, você poderá reativar a simulação do local e o simulador funcionará bem a partir de então.

Paolo
fonte
Isso funcionou até certo ponto para mim. Pelo menos eu tenho que ver o diálogo
CppChase
2

Swift 4 e iOS 11 :

Certifique-se de adicionar linhas de privacidade ( sempre e quandoInutilizar ) ao seu .plistarquivo e adicionar CoreLocationFramework ao seu projeto

A caixa de diálogo de permissão de local aparece corretamente quando eu mudei:

locationManager.requestAlwaysAuthorization()

com:

locationManager.requestWhenInUseAuthorization()

PS .: Tentei TODOS os conselhos e todas as falhas (solicite autorização para viewDidLoad, em varvez de letpara locationManager, não inicie startUpdatingLocation()após solicitação .. Acho que é um bug e espero que o resolvam o mais rápido possível ..

Alessandro Ornano
fonte
Também segui todos os conselhos, mas sempre tenho o mesmo problema. A caixa de diálogo de permissão de localização aparece brevemente e desaparece imediatamente. Em seguida, minha permissão da caixa de diálogo de notificação é exibida (essa é normal); quando pressiono aceitar ou recusar, outra permissão de local aparece (desta vez ela permanece e me permite aceitar ou recusar).
@BitoQ Sim, para mim também. Mesma situação, mas pelo menos podemos ver essa caixa de diálogo, espero que, com o próximo iOS 11.1, eles corrijam esse bug.
Alessandro Ornano 11/11
1

A solução SWIFT 4 @Zoli terá a seguinte aparência:

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
fonte
0

você mais define a variável locationManager como objeto global.

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

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

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

Eu conheci a mesma situação sua.

  • Minha solução foi alterada de variável local para instância de membro.
  • A causa foi que a instância local? Era inválida após a conclusão do método, que inclui a variável local (de extend my locationManager)
  • Meu Env .: Xcode9.3.1
#importar 
@interface ViewController ()

@fim

@implementation ViewController
@synthesize locManager; // depois de
- (vazio) viewDidLoad {
    [super viewDidLoad];
    // Faça qualquer configuração adicional depois de carregar a visualização, geralmente de uma ponta.

    // MyLocationService * locManager = [[alocação do BSNLocationService] init: nil]; // antes. o loc. delegado não funcionou porque a instância se tornou inválida após esse método.
    self-> locManager = [[MyLocationService aloc] init: nil]; // depois de
    locManager.startService;
}

user2058374
fonte