Pytanie Jak korzystać z "Pokaż lokalizację użytkownika" MKMapView w iOS8?


Gdy dodajesz MKMapView komponent do widoku w Interface Builder, są pola wyboru, które pozwalają skonfigurować to, co pokazuje:

enter image description here

Gdy zaznaczysz "Lokalizacja użytkownika", automatycznie wyświetli się lokalizacja użytkownika na mapie.

Jednak od czasu instalacji systemu iOS 8 należy poprosić o pozwolenie na lokalizację przed wyświetleniem lokalizacji użytkownika. Jeśli tego nie zrobisz, pojawi się komunikat "Próba uruchomienia aktualizacji lokalizacji MapKit bez monitowania" w konsoli.

Więc dodałem NSLocationWhenInUseUsageDescription klucz do pliku plist, i dodał ten kod do viewDidLoad:

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

To jednak nie działa. Dostaję wyskakujące okienko z prośbą o pozwolenie, ale zanim wybieram odpowiedź, sama się ukrywa, mapa ładuje się pod nią i otrzymuję ostrzeżenie w konsoli.

Wiem, że mogę ustawić showsUserLocation właściwość w kodzie, tylko po uzyskaniu pozwolenia; ale chodzi mi o to, że jest to pole wyboru w IB, które powinno robić to samo, z wyjątkiem, że natychmiast rozpoczyna śledzenie. Czy to oznacza, że ​​nie powinniśmy używać tego pola wyboru od czasu iOS 8? Czy używam go niepoprawnie?

-

Aktualizacja: w rzeczywistości wyskakujące okienko ukrywa się samo, niezależnie od tego, czy "pokazuje lokalizację użytkownika" jest ustawione czy nie. Próbowałem to zrobić w viewWillAppear lub viewDidAppear zamiast tego, ale to nie pomogło. Więc nie jestem pewien, gdzie dokładnie powinienem zadzwonić requestwhenInUseAuthorization podczas korzystania z MKMapView...


11
2017-12-01 14:24


pochodzenie




Odpowiedzi:


Twój CLLocationManager instancja jest zwalniana przez ARC po zakończeniu wykonywania metody. Zaraz po zwolnieniu instancji okno zniknęło. Rozwiązanie było raczej proste. Zmień instancję CLLocationManager z bycia zmienną poziomu metody na instancję klasy i wykonaj ją Silny - to jest dla ObjC :)

Dla Swift ... zrób coś takiego:

    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()
            }
    ...
    }

więc ... nie używaj CLLocationManager().requestWhenInUseAuthorization() - zamiast tego użyj locationManager.requestWhenInUseAuthorization() - menedżer locationManager zadeklarował wcześniej


9
2017-12-02 21:16



Ach, masz rację, ARC sprawia, że ​​całkowicie zapominam o zarządzaniu pamięcią, co czasami prowadzi do takich rzeczy. Wygląda na to, że w ogóle nie wyświetla się pop-up, jeśli nie zatrzymam menedżera. Jeśli tak, to działa tak, jak powinno, dzięki. - Kuba Suder
Cieszę się że mogę pomóc! :) - TonyMkenu
Miło myślę, że odniesienie do delegata nie wystarczy, aby utrzymać instancję w pobliżu. Dzięki jeszcze raz! - Quincy
@Quincy wellcome! Szczęśliwe kodowanie - TonyMkenu
@Quincy Delegaci powinni zawsze BYĆ SŁABY, w przeciwnym razie wszędzie będziesz mieć cykle zatrzymania. - Beau Nouvelle


requestWhenInUseAuthorization jest asynchroniczny - upewnij się, że słyszysz status zmiany autoryzacji w delegacie widoku mapy, zanim faktycznie spróbujesz śledzić lub pokazać lokalizację użytkownika.


0
2017-12-01 19:36



Ale o to chodzi, nie zaczynam śledzić lokalizacji użytkownika w kodzie. Jeśli zaznaczę "Pokaż: położenie użytkownika" w IB, to program ładujący NIB zrobi to i uruchomi go automatycznie i asynchronicznie z tym, co robię w delegacie / kontrolerze. Pytam więc, czy istnieje sposób, aby zrobić to poprawnie, używając tego pola wyboru w iOS 8? - Kuba Suder