Swift - 位置提示不会很快发生

时间:2017-03-22 15:44:20

标签: ios swift core-location locationmanager

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

这是因为隐私 - 位置提示不会很快发生,即使请求在代码中较早。在应用程序崩溃后关闭应用程序后,就会提示我允许我的位置。

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

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

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

import UIKit
import MapKit
import CoreLocation

class ShopTableViewController: UITableViewController, CLLocationManagerDelegate {




@IBAction func filterBack(_ sender: Any) {
        getLocale()
        shops.sort() { $0.distance < $1.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)
    }


}
}

我做错了什么?

2 个答案:

答案 0 :(得分:1)

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

但是,在viewDidLoad中,您可以致电

checkLocationAuthorizationStatus()

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

这会触发locationManager在授权之前启动。看看这个(有点旧的)链接http://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)")
}

答案 1 :(得分:0)

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