我在Swift iOS应用中使用MapKit。 问题是我在使用应用程序时请求访问用户位置的权限,但是第一次在iPhone中运行应用程序时,它会在启动画面中保持冻结状态,因为权限请求不是&# 39; t弹出,但是,如果我按下主页按钮,弹出窗口似乎要求许可。如果我接受,那么下一次运行该应用程序正常,但它不应该像这样工作。 所以在代码中,调试器在这里崩溃,因为他无法获得权限:
let initialLocation:CLLocation = CLLocation(latitude: (locationManager.location?.coordinate.latitude)!, longitude: (locationManager.location?.coordinate.longitude)!)
指出下一个问题:线程1:EXC_BREAKPOINT(代码= 1,子代码= 0x1000b5d00)
所以,我已经在viewWillAppear方法中询问权限了:
let locationManager = CLLocationManager()
// Ask for Authorisation from the User.
// locationManager.requestAlwaysAuthorization()
// For use in foreground
locationManager.requestWhenInUseAuthorization()
//locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
//locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
mapView.showsUserLocation = true
}
我还有Info.plist中的条目:隐私 - 使用时的位置使用说明。
为什么弹出窗口不显示在前景中而是显示在后台?
提前感谢您的帮助。
干杯
编辑:
我在地图视图前面有一个带徽标的启动画面。这可能是问题吗?
编辑2回答@Dan Clark
好的,我已经在viewDidLoad中添加了此项检查,如下所示:
编辑3
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
print("viewdidload")
if CLLocationManager.authorizationStatus() != .AuthorizedWhenInUse // Check authorization for location tracking
{
print("requestingautorization")
locationManager.requestWhenInUseAuthorization()
print("afterrequestingauthorization")
// LocationManager will callbackdidChange... once user responds
} else {
print("startupdatinglocation")
addPins(locationManager)
}
}
但请求授权的弹出窗口没有出现:(我之前和之后都有两张照片,但弹出窗口没有显示。
我还在同一个班级中添加了你写的我的功能。
@nonobjc func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
print("instatuscheck")
switch status
{
case .AuthorizedWhenInUse:
print("statusauthorized")
addPins(manager)
default:
print("statusdefault")
manager.requestWhenInUseAuthorization()
// User denied access, handle as appropriate
}
}
但我不明白......当授权状态发生变化时,会自动调用此功能吗?
再次感谢您的帮助:)
答案 0 :(得分:0)
问题是,在您提出请求后,您可能需要一段时间才能获得LocationManager的授权。因此,在您第一次尝试之后,在您的请求到达关闭之前,您没有获得授权。我已经通过测试授权来解决这个问题,如果我没有,则在开始位置更新之前输入请求然后等待回调到didChangeAuthorizationStatus。如果我已经获得授权,我会立即开始更新位置。
第二次运行应用程序时,您拥有授权,因此不会发生延迟,您可以继续使用。
要尝试这种方法,请在ViewDidLoad中包含此部分(我假设您不必在视图出现时运行此部分,但仅在首次启动时运行):
if CLLocationManager.authorizationStatus() != .authorizedAlways // Check authorization for location tracking
{
locationManager.requestAlwaysAuthorization() // LocationManager will callbackdidChange... once user responds
} else {
locationManager.startUpdatingLocation()
}
将此委托函数添加到您的类中,以便在您获得授权后由LocationManager调用:
// If we've been authorized to use location, start the processes, otherwise abort the operation
// since we can't proceed without locations
@nonobjc func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status
{
case .authorizedAlways:
locationManager.startUpdatingLocation()
default:
// User denied access, handle as appropriate
}
}
这是我用来实例化/配置locationManager的代码:
lazy var locationManager: CLLocationManager = {
[unowned self] in
var _locationManager = CLLocationManager()
_locationManager.delegate = self
_locationManager.desiredAccuracy = [a user setting in my app]
_locationManager.allowsBackgroundLocationUpdates = true
_locationManager.pausesLocationUpdatesAutomatically = false // So doesn't shut off if user stops to rest
_locationManager.activityType = .fitness
_locationManager.distanceFilter = Double([a user setting in my app])
return _locationManager
}()
这对我有用,所以希望它会有所帮助。