Диалог разрешения текущего местоположения исчезает слишком быстро - PullRequest
160 голосов
/ 25 октября 2011

Мое приложение берет местоположение пользователя, получает координаты и обеспечивает расстояние до или от пункта назначения или источника. Все эти возможные пункты назначения показаны в табличном представлении, поэтому я получаю координаты пользователей одновременно с заполнением таблицы. Единственное, что окно предупреждений, запрашивающее местоположение пользователя, появляется, а затем исчезает так быстро, что по нему невозможно щелкнуть!

Есть ли способ вручную представить это предупреждение при первой загрузке приложения? Я попытался определить местоположение пользователя при загрузке приложения, чтобы попытаться вызвать предупреждение, но это не сработало.

Ответы [ 11 ]

636 голосов
/ 28 февраля 2012

Хотя это трудно отследить, решение для этого довольно простое.

Путем многочисленных проб и ошибок я обнаружил, что хотя диалоговое окно доступа к местоположению появляется при первом доступе к любым службам определения местоположения в приложении, оно исчезает само по себе (без какого-либо взаимодействия с пользователем), если CLLocationManager объект освобождается до того, как пользователь откликнется на диалог.

Я создал CLLocationManager экземпляр в моем viewDidLoad методе. Поскольку это был локальный экземпляр метода, этот экземпляр был освобожден ARC после выполнения метода. Как только экземпляр был выпущен, диалог исчез. Решение было довольно простым. Измените экземпляр CLLocationManager с переменной уровня метода на переменную экземпляра уровня класса. Теперь экземпляр CLLocationManager освобождается только после выгрузки класса.

5 голосов
/ 19 марта 2015

Тот же симптом, другая причина: не вызывать startUpdatingLocation более одного раза подряд .

Я случайно структурировал вещи так, что код непреднамеренно вызывал startUpdatingLocationдва раза подряд, что, видимо, плохо.Возможно, это также имело отношение к выбору очереди, так как я ждал начала обновления в ожидании результата сетевого запроса, но мне не нужно было использовать магию GCD, чтобы это исправить ... просто нужно было убедиться, что яне повторил начало.

Надеюсь, кто-то сможет извлечь выгоду из моей боли.:)

4 голосов
/ 17 июля 2012

Я знаю, что это очень поздний ответ. Но это может кому-то помочь. Я также столкнулся с той же проблемой и потратил час, чтобы определить проблему. Сначала мой код был таким:

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

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

    [locationManager release];

Теперь оповещение о местоположении исчезло быстро. Когда я раскомментирую последнюю строку, она работает правильно.

   // [locationManager release];
4 голосов
/ 17 ноября 2011

Я попадаю в ту же проблему (хотя бы по симптомам). В моем случае проблема была в методе - (void)applicationWillResignActive:(UIApplication *)application;, где я выпускал свой экземпляр CLLocationManager как часть подготовки к фоновому переходу. Когда я удалил его и оставил его только в - (void)applicationDidEnterBackground:(UIApplication *)application;, проблема исчезла.
Хитрость в том, что оповещение о расположении ядра МОЖЕТ приостановить ваше приложение, пока оно все еще находится на переднем плане.
Надеюсь, что оно поможет вам, взял меня много времени нашел этого ублюдка :) 1006 *

3 голосов
/ 12 сентября 2013

Я тоже столкнулся с этой проблемой, но решение в моем случае оказалось полностью отличным от принятого ответа.

В моем приложении я звонил stopUpdatingLocation с applicationWillResignActive.Это было проблемой, потому что applicationWillResignActive вызывается, когда появляется диалоговое окно разрешения.Это вызывало stopUpdatingLocation сразу после startUpdatingLocation, поэтому диалог немедленно исчезал.

Решением было просто вызвать stopUpdatingLocation вместо applicationDidEnterBackground.

2 голосов
/ 09 октября 2017

Swift 4 и iOS 11 :

Обязательно добавьте строки конфиденциальности (оба всегда и whenInUse ) к вашему .plist файл и добавьте CoreLocation Framework в ваш проект

Диалог разрешения местоположения отображается правильно, когда я изменил:

locationManager.requestAlwaysAuthorization()

с:

locationManager.requestWhenInUseAuthorization()

PS .: Я пробовал ALL советы и все не удается (запросить авторизацию на viewDidLoad, var вместо let для locationManager, не запускать startUpdatingLocation() послезапрос .. Я думаю, что это ошибка, и я надеюсь, что они решат ее как можно скорее ..

2 голосов
/ 22 января 2017

Это происходило со мной во время использования симулятора iOS.Я определил, что это происходило, потому что моя Схема выполнения моделировала местоположение.Я думаю, что это имеет тот же эффект, что и вызов locationManager.startUpdatingLocation() при запуске, поэтому диалоговое окно закрывалось.

Снятие флажка «Allow Location Simulation» в диалоговом окне «Edit Schemes» решило проблему.Как только он будет работать так, как вы хотите, и разрешение будет установлено, вы можете снова включить симуляцию местоположения, и с этого момента симулятор будет работать нормально.

1 голос
/ 09 августа 2017

SWIFT 4 Решение @Zoli будет выглядеть так:

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 голосов
/ 23 июня 2019

Я столкнулся с подобной ситуацией.После отладки я обнаружил, что

let locationManager = CLLocationManager()

вызывается в области действия метода, но его следует вызывать глобально.

Почему?

В двух словах locationManager был выпущен послеметод вернулся.Но это не должно быть выпущено, пока пользователь не даст или не запретит разрешение

0 голосов
/ 25 мая 2018

Я встречал ту же ситуацию, что и ты.

  • Мое решение было изменено с локальной переменной на экземпляр члена.
  • Причиной было то, что локальный экземпляр был недействителен после завершения метода, который включает локальную переменную (из extension my locationManager)
  • Мой Env .: Xcode9.3.1

#import 
@interface ViewController ()

@end

@implementation ViewController
@synthesize locManager; // after
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    //MyLocationService *locManager = [[BSNLocationService alloc]init:nil]; // before. the loc. delegate did not work because the instance became invalid after this method.
    self->locManager= [[MyLocationService alloc]init:nil]; // after
    locManager.startService;
}

...