Ошибка при вызове requestWhenInUseAuthorization для разрешений расположения - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь получить местоположение пользователя в приложении, используя менеджер местоположения; как объяснено в документации Apple, я создал следующий метод:

func startReceivingLocationChanges() {
    let authorizationStatus = CLLocationManager.authorizationStatus()
    if authorizationStatus != .authorizedWhenInUse && authorizationStatus != .authorizedAlways {
        locationManager.requestWhenInUseAuthorization()
        startReceivingLocationChanges()
        return
    }

    if !CLLocationManager.locationServicesEnabled() {
        displayError(withTitle: "Location Not Available", withDescription: "Enable Location Services at Settings > Privacy > Location Services", sender: self)
        return
    }

    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = 100.0  // In meters.
    locationManager.pausesLocationUpdatesAutomatically = true
    locationManager.activityType = .other
    locationManager.delegate = self
    locationManager.startUpdatingLocation()
}

Но, когда я запускаю приложение, эта ошибка выдает ошибку «Поток 1: EXC_BAD_ACCESS (код = 2, адрес = 0x16f0a7f60)» рядом со строкой:

locationManager.requestWhenInUseAuthorization()

Я указываю, что я добавил относительные ключи "Конфиденциальность - Местоположение всегда и когда используется описание использования" и "Конфиденциальность - Местоположение, когда используется описание использования" внутри info.plist.

Кто-нибудь знает, что вызывает проблему? Спасибо.

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

В вашем коде есть несколько ошибок, таких как рекурсия, в случае, если пользователь не дает разрешения на использование, поэтому посмотрите на мой код. Предполагая, что вы добавили ключи "Конфиденциальность - Местоположение всегда и когда используется описание использования" и "Конфиденциальность - Местоположение, когда используется описание использования" внутри info.plist. Приведенный ниже код работает без проблем и Apple рекомендуется.

import Foundation
import CoreLocation

typealias LocateMeCallback = (_ location: CLLocation?) -> Void

class LocationTracker: NSObject {

    static let shared = LocationTracker()

    var locationManager: CLLocationManager = {
       let locationManager = CLLocationManager()
       locationManager.activityType = .automotiveNavigation
       locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
       locationManager.distanceFilter = 10

       return locationManager
    }()

    var locateMeCallback: LocateMeCallback?
    var currentLocation: CLLocation?
    var isCurrentLocationAvailable: Bool {
        return currentLocation != nil
    }

    func enableLocationServices() {
        locationManager.delegate = self
        switch CLLocationManager.authorizationStatus() {
        case .notDetermined:
            // Request when-in-use authorization initially
            locationManager.requestWhenInUseAuthorization()
        case .restricted, .denied:
            // Disable location features
            print("Fail permission to get current location of user")
        case .authorizedWhenInUse:
            // Enable basic location features
            enableMyWhenInUseFeatures()
       case .authorizedAlways:
            // Enable any of your app's location features
            enableMyAlwaysFeatures()
       }
    }

    func enableMyWhenInUseFeatures() {
       locationManager.startUpdatingLocation()
    }

    func enableMyAlwaysFeatures() {
       locationManager.allowsBackgroundLocationUpdates = true
       locationManager.pausesLocationUpdatesAutomatically = true
       locationManager.startUpdatingLocation()
    }

    func locateMe(callback: @escaping LocateMeCallback) {
        self.locateMeCallback = callback
        enableLocationServices()
    }

    private override init() {}

}


// MARK: - CLLocationManagerDelegate
extension LocationTracker: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.first else { return }
        print("locations = \(location.coordinate.latitude) \(location.coordinate.longitude)")
        locateMeCallback?(location)
    }
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print(error.localizedDescription)
    }
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        enableLocationServices()
    }
}

Использование

LocationTracker.shared.locateMe {  location in
            guard let location = location else {
                print("Cann't retrieve current location of user")
                return
            }
           // do what ever you want to do with location            
        }
0 голосов
/ 27 августа 2018

Нашел проблему, это было как-то связано с рекурсивным вызовом функции

startReceivingLocationChanges

внутри самой функции. Я решил это, запросив разрешения для определения местоположения внутри метода ViewDidLoad и удалив рекурсивный вызов.

...