Как использовать MKMapView "Показывает местоположение пользователя" в iOS8?

Когда вы добавляете компонент MKMapView к представлению в Interface Builder, есть флажки, которые позволяют вам настроить то, что он показывает:

enter image description here

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

Однако, начиная с iOS 8, вы должны запросить разрешение на местоположение, прежде чем показывать местоположение пользователя. Если вы этого не сделаете, вы получите сообщение "Попытка запуска обновления MapKit без предупреждения" на консоли.

Итак, я добавил ключ NSLocationWhenInUseUsageDescription к plist и добавил этот код к viewDidLoad:

if CLLocationManager.authorizationStatus() == .NotDetermined {
    CLLocationManager().requestWhenInUseAuthorization()
}

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

Я знаю, что я могу установить свойство showsUserLocation в коде вместо этого, только после получения разрешения; но я хочу сказать, что этот флажок установлен в IB, который должен делать то же самое, за исключением того, что он сразу же начинает отслеживание. Означает ли это, что мы не должны использовать этот флажок вообще с iOS 8? Или я использую его неправильно?

-

Обновление: на самом деле всплывающее окно скрывается самостоятельно, независимо от того, установлено ли "отображение местоположения пользователя" или нет. Я попытался сделать это в viewWillAppear или viewDidAppear вместо этого, но это не помогло. Поэтому я не уверен, где именно я должен был называть requestwhenInUseAuthorization при использовании MKMapView...

Ответ 1

Ваш экземпляр CLLocationManager будет выпущен ARC после завершения выполненного метода. Как только экземпляр был выпущен, диалоговое окно исчезло. Решение было довольно простым. Измените экземпляр CLLocationManager как переменную уровня метода, которая будет переменной экземпляра класса, и сделайте ее Сильной - это для ObjC:)

Для Swift... сделайте что-нибудь подобное:

    class YourViewController: UIViewController,CLLocationManagerDelegate {
    ...
    let locationManager = CLLocationManager()


    override func viewDidLoad() {
            super.viewDidLoad()
            // Ask for permission for location
            locationManager.delegate = self

            if(locationManager.respondsToSelector("requestAlwaysAuthorization")) {
                locationManager.requestAlwaysAuthorization()
                //or
                //locationManager.requestWhenInUseAuthorization()
            }
    ...
    }

поэтому... не используйте CLLocationManager().requestWhenInUseAuthorization() - вместо этого используйте locationManager.requestWhenInUseAuthorization() - locationManager объявлен раньше

Ответ 2

requestWhenInUseAuthorization является асинхронным - убедитесь, что вы слушаете статус изменения авторизации в своем делете делегата на карте, прежде чем пытаться отслеживать или показывать местоположение пользователя.