为位置权限调用 requestWhenInUseAuthorization 时出错
Error when invoke requestWhenInUseAuthorization for location permissions
我正在尝试使用位置管理器检索用户在应用中的位置;如 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()
}
但是,当我启动该应用程序时,此崩溃在行附近显示错误 "Thread 1: EXC_BAD_ACCESS (code=2, address=0x16f0a7f60)":
locationManager.requestWhenInUseAuthorization()
我指定我在 info.plist.
中添加了相关的 "Privacy - Location Always and When In Use Usage Description" 和 "Privacy - Location When In Use Usage Description" 键
有谁知道导致这个问题的原因吗?谢谢
找到问题,它与函数的递归调用有某种关系
startReceivingLocationChanges
在函数本身内部。我解决了在 ViewDidLoad 方法中请求位置权限并删除递归调用的问题。
你的代码中有几个错误,比如递归,以防用户在使用时不授予权限,所以请看我的代码。假设您在 info.plist 中添加了 "Privacy - Location Always and When In Use Usage Description" 和 "Privacy - Location When In Use Usage Description" 键。下面的代码完美无误,苹果推荐。
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
}
我正在尝试使用位置管理器检索用户在应用中的位置;如 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()
}
但是,当我启动该应用程序时,此崩溃在行附近显示错误 "Thread 1: EXC_BAD_ACCESS (code=2, address=0x16f0a7f60)":
locationManager.requestWhenInUseAuthorization()
我指定我在 info.plist.
中添加了相关的 "Privacy - Location Always and When In Use Usage Description" 和 "Privacy - Location When In Use Usage Description" 键有谁知道导致这个问题的原因吗?谢谢
找到问题,它与函数的递归调用有某种关系
startReceivingLocationChanges
在函数本身内部。我解决了在 ViewDidLoad 方法中请求位置权限并删除递归调用的问题。
你的代码中有几个错误,比如递归,以防用户在使用时不授予权限,所以请看我的代码。假设您在 info.plist 中添加了 "Privacy - Location Always and When In Use Usage Description" 和 "Privacy - Location When In Use Usage Description" 键。下面的代码完美无误,苹果推荐。
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
}