应用不要求访问位置的权限,弹出窗口保留在后台

时间:2016-11-10 07:37:48

标签: ios swift permissions location mapkit

我在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

    }
}

但我不明白......当授权状态发生变化时,会自动调用此功能吗?

再次感谢您的帮助:)

1 个答案:

答案 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
    }()

这对我有用,所以希望它会有所帮助。