【问题标题】:location authorization alert showing up after app closes应用关闭后显示位置授权警报
【发布时间】:2017-07-10 12:17:00
【问题描述】:

我创建了一个单例类来处理位置授权,因为我的应用程序中的多个视图都需要它。所以我创建了下面的 Location.swift 类。

注意:我已正确添加到 Info.plist,并查看了其他几篇帖子,但似乎没有一个解决这个问题(至少我没有找到)

protocol LocationServiceDelegate {
    func tracingLocation(currentLocation: CLLocation)
    func tracingLocationDidFailWithError(error: NSError)
}

class Location:  NSObject,CLLocationManagerDelegate {

    var latitude: Double!
    var longitude: Double!
    var currentLocation : CLLocation!

    var locationManager: CLLocationManager?
    var lastLocation: CLLocation?
    var delegate: LocationServiceDelegate?

    static let sharedInstance:Location = {
        let instance = Location()
        return instance
    }()

    override init() {
        super.init()
        self.locationManager = CLLocationManager()
        self.locationManager?.delegate = self

        guard let locationManagers = self.locationManager else {
            return
        }

        if CLLocationManager.authorizationStatus() == .notDetermined {
            locationManagers.requestWhenInUseAuthorization()
        }

        locationManagers.desiredAccuracy = kCLLocationAccuracyBest
        locationManagers.pausesLocationUpdatesAutomatically = false
        locationManagers.distanceFilter = 0.1

    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.last else {
            return
        }
        self.lastLocation = location
        updateLocation(currentLocation: location)

    }

    @nonobjc func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch status {
        case .notDetermined:
            locationManager?.requestWhenInUseAuthorization()
            break
        case .authorizedWhenInUse:
            locationManager?.startUpdatingLocation()
            break
        case .authorizedAlways:
            locationManager?.startUpdatingLocation()
            break
        case .restricted:
            // restricted by e.g. parental controls. User can't enable Location Services
            break
        case .denied:
            // user denied your app access to Location Services, but can grant access from Settings.app
            break
        }
    }


    // Private function
    private func updateLocation(currentLocation: CLLocation){

        guard let delegate = self.delegate else {
            return
        }

        delegate.tracingLocation(currentLocation: currentLocation)
    }

    private func updateLocationDidFailWithError(error: NSError) {

        guard let delegate = self.delegate else {
            return
        }

        delegate.tracingLocationDidFailWithError(error: error)
    }

    func startUpdatingLocation() {
        print("Starting Location Updates")
        self.locationManager?.startUpdatingLocation()
        currentLocation = locationManager?.location
        Location.sharedInstance.latitude = currentLocation.coordinate.latitude
        Location.sharedInstance.longitude = currentLocation.coordinate.longitude
        print(Location.sharedInstance.latitude, Location.sharedInstance.longitude)
        //        self.locationManager?.startMonitoringSignificantLocationChanges()
    }

    func stopUpdatingLocation() {
        print("Stop Location Updates")
        self.locationManager?.stopUpdatingLocation()

    }


}

我的应用程序崩溃了,我认为是因为一开始没有设置位置授权。有趣的是,在您离开应用程序之前,提示用户允许定位服务的请求警报不会出现。

关闭应用并接受定位服务后,应用就可以正常运行。所以我的问题是,为什么不显示警报?

值得注意的是,这仅通过实际设备发生。在模拟器中,当初始视图加载时,警报会按预期弹出。

我应该加载和显示数据的第一个视图如下:

import UIKit
import Alamofire

class CurrentWeatherVC: UIViewController {

    @IBOutlet weak var locationLabel: UILabel!
    @IBOutlet weak var weatherIcon: UIImageView!
    @IBOutlet weak var currentTempLabel: UILabel!
    @IBOutlet weak var weatherTypeLabel: UILabel!
    var currentWeather : CurrentWeather!

    override func viewDidLoad() {
        super.viewDidLoad()
        Location.sharedInstance.locationManager(manager: Location.sharedInstance.locationManager, didChangeAuthorizationStatus: .authorizedWhenInUse)
        currentWeather = CurrentWeather()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Location.sharedInstance.startUpdatingLocation()
        currentWeather.downloadWeatherDetails {
                   self.updateMainUI()
        }
    }

    func updateMainUI() {
        //Double value convterted to string for current temp.
        //Added the degree symbol here
        //For forecast it gets added in before saved into list so be aware of that. 
        currentTempLabel.text = "\(currentWeather.currentTemp)°"
        weatherTypeLabel.text = currentWeather.weatherType
        locationLabel.text = currentWeather.cityName
        weatherIcon.image = UIImage(named: currentWeather.weatherType)
    }

}

【问题讨论】:

  • 我不会检查当前的授权状态;每次只在使用时请求权限。 iOS 只会提示用户一次。
  • @Paulw11 是的,我也尝试过请求它,但同样的问题仍然存在。在我单击主页按钮并离开应用程序之前,不会弹出警报。在模拟器中警报正确显示,这很奇怪。也许这与视图未在主视图中加载有关?
  • 听起来您正在阻塞主线程或从后台线程更新 UI。您正在从视图控制器调用委托方法,您不应该这样做。只有CLLocationManager 应该调用它的委托函数。

标签: ios cllocationmanager cllocation


【解决方案1】:

我怀疑downloadWeatherDetailss 的实现使用了dataTask 或在后台运行的其他NSURLSession 方法之一。

确保仅在 mainQueue 上调用 UI 内容:

// ...
DispatchQueue.main.async {
    self.updateMainUI()
}
// ...

【讨论】:

    猜你喜欢
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    相关资源
    最近更新 更多