Swift - 位置提示没有及时发生

Swift - Location Prompt not happening soon enough

我正在构建一个基于位置的应用程序,列出附近的咖啡馆。应用程序在设备上首次构建时不断崩溃,因为位置一直返回为 nil。

这是因为隐私 - 位置提示没有足够快地发生,即使请求在代码中更早。在我崩溃后关闭应用程序后,系统会提示我允许我的位置。

我有三个入职屏幕,当我到达这个 tableviewcontroller 时,它就崩溃了。

如果我进入“设置”>“隐私”>“位置”并手动启用位置服务,该应用程序运行良好。

这是我的代码(我删除了大量不必要的东西):

import UIKit
import MapKit
import CoreLocation

class ShopTableViewController: UITableViewController, CLLocationManagerDelegate {




@IBAction func filterBack(_ sender: Any) {
        getLocale()
        shops.sort() { [=11=].distance < .distance }
        shops.removeAll()
        loadShops()
        sortList()

}


//MARK: Properties

var shops = [CoffeeShop]()
var filteredShops = [CoffeeShop]()
var objects: [CoffeeShop] = []
var locationManager = CLLocationManager()
func checkLocationAuthorizationStatus() {
    if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
        locationManager.requestWhenInUseAuthorization()
    }
}
var currentLocation = CLLocation!.self
var userLatitude:CLLocationDegrees! = 0
var userLongitude:CLLocationDegrees! = 0
var locValue:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 1.0, longitude: 1.0)
var refresher: UIRefreshControl! = UIRefreshControl()





func getLocale() {

    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
    self.locationManager.startMonitoringSignificantLocationChanges()

    userLatitude  = self.locationManager.location?.coordinate.latitude
    userLongitude = self.locationManager.location?.coordinate.longitude
    print("\(userLatitude), \(userLongitude)")
}



override func viewDidLoad() {
    super.viewDidLoad()

    self.locationManager = CLLocationManager()
    /// self.locationManager.requestWhenInUseAuthorization()
    checkLocationAuthorizationStatus()

    self.locationManager.delegate = self
    self.locationManager.startUpdatingLocation()
    if CLLocationManager.locationServicesEnabled()
    {
        getLocale()

    }

    let locValue = self.locationManager.location?.coordinate
    noHeight()
    loadShops()
    sortList()
    print("\(locValue?.latitude), \(locValue?.longitude)")

    refresher = UIRefreshControl()
    refresher.addTarget(self, action: #selector(ShopTableViewController.handleRefresh), for: UIControlEvents.valueChanged)


    if #available(iOS 10, *) {
        shopTable.refreshControl = refresher
    } else {
        shopTable.addSubview(refresher)
    }


}
}

我做错了什么?

您需要等待授权响应才能使用定位服务。 您现在正在做的是请求授权和立即启动位置服务。您需要确定,应用程序在获取位置之前已获得授权。

requestWhenInUseAuthorization() 是一个异步方法,所以包装它的方法 checkLocationAuthorizationStatus() 也是异步的。

但是,在您的 viewDidLoad 中,您调用

checkLocationAuthorizationStatus()

self.locationManager.delegate = self
self.locationManager.startUpdatingLocation()

这会触发 locationManager 在获得授权之前启动。看看这里(有点旧)linkhttp://nshipster.com/core-location-in-ios-8/

例子

一定要符合CLLocationManagerDelegate

override func viewDidLoad() {
    super.viewDidLoad()
    self.locationManager = CLLocationManager()
    self.locationManager.delegate = self
    if CLLocationManager.authorizationStatus() == .notDetermined {
        locationManager.requestWhenInUseAuthorization()
    } else if CLLocationManager.authorizationStatus() == . authorizedWhenInUse {
        startTrackingLocation()
    }
}

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    if status == .authorizedAlways || status == .authorizedWhenInUse {
        startTrackingLocation()
        // ...
    }
}

func startTrackingLocation() {
    locationManager.startUpdatingLocation()
    getLocale()
    //not clear which of these methods require location
    let locValue = self.locationManager.location?.coordinate
    noHeight()
    loadShops()
    sortList()
    print("\(locValue?.latitude), \(locValue?.longitude)")
}