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)")
}
我正在构建一个基于位置的应用程序,列出附近的咖啡馆。应用程序在设备上首次构建时不断崩溃,因为位置一直返回为 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)")
}