Диалог разрешения текущего местоположения слишком быстро исчезает

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

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

Ответ 1

Пока сложно отследить, решение для этого довольно просто.

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

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

Ответ 2

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

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

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

Ответ 3

Я попадаю в ту же проблему (по крайней мере, по симптомам). В моем случае проблема была в методе - (void)applicationWillResignActive:(UIApplication *)application;, где я выпускал экземпляр CLLocationManager как часть подготовки к фоновому переходу. Когда я удалил его и оставил его только в - (void)applicationDidEnterBackground:(UIApplication *)application;, проблема исчезла.
Сложная часть заключается в том, что предупреждение Core Location DO приостанавливает ваше приложение, пока оно остается на переднем плане.
Надеюсь, что это поможет вам, взял меня много времени, чтобы найти этого ублюдка:)

Ответ 4

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

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

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

    [locationManager release];

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

   // [locationManager release];

Ответ 5

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

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

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

Ответ 6

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

Отметка флажка "Разрешить определение местоположения" в диалоговом окне "Редактировать схемы" устранила проблему. После того, как он будет работать так, как вы хотите, и разрешение будет установлено, вы можете снова включить симуляцию местоположения, и симулятор будет работать нормально с этого момента.

Ответ 7

Swift 4 и iOS 11:

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

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

locationManager.requestAlwaysAuthorization()

с:

locationManager.requestWhenInUseAuthorization()

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

Ответ 8

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

Ответ 9

вы чаще определяете переменную locationManager как глобальный объект.

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

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

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

Ответ 10

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

  • Мое решение было изменено с локальной переменной на экземпляр члена.
  • Причиной было то, что локальный экземпляр был недопустим после завершения метода, который включает локальную переменную (из 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;
}

Ответ 11

Это происходит, когда вы создаете локальную переменную класса или оболочки внутри функции/метода. Создайте переменную экземпляра, которая должна содержать класс местоположения/оболочку

Ответ 12

Я сталкивался с подобной ситуацией. После отладки я нашел

let locationManager = CLLocationManager()

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

Зачем?

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