在我的iOS应用程序中,我正在请求用户获得设备位置的权限。在我的主ViewController上,我有一个导航栏按钮,在点击该按钮时,它将询问用户使用许可。如果用户点击“确定”,它将被发送到显示本地数据的视图控制器。如果用户点击取消,则什么也不会发生。我还会弹出一个窗口,提示用户何时以及是否再次轻按“位置”按钮,以将其重定向到设置以授权位置设置(如果先前已取消的话)。
该应用程序可以按照我在模拟器中的预期运行,但是当在设备上使用时,当用户点击“确定”以允许位置使用时,它会选择连接到本地View Controller,但它连续进行了2到3次。
segue从主视图控制器转到本地视图控制器,并使用IBAction从按钮点击请求权限。
位置信息在主视图控制器中获得,并传递给本地控制器。本地控制器按预期显示所有内容。
如何防止对同一个View Controller进行这种双重或三次选择?
下面是我的代码:
SELECT * FROM address WHERE address REGEXP '[[:<:]]demo[[:>:]]' AND 'demo' REGEXP '[0-9]'
答案 0 :(得分:2)
正如 superpuccio 所述,主要问题是didUpdateLocations
委托函数被多次调用。我也不知道您为什么要检查authorizationStatus
函数中的didUpdateLocations
,因为到那时,用户已经允许位置访问。我认为该函数应如下所示:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// check for a location that suits your needs
guard let location = locations.last, location.horizontalAccuracy > 0 else { return }
// prevent the manager from updating the location and sending more location events
manager.delegate = nil
manager.stopUpdatingLocation()
// update the local variables
latitude = location.coordinate.latitude
longitude = location.coordinate.longitude
// perform the segue
performSegue(withIdentifier: "toLocal", sender: nil)
}
由于还有更多问题,例如在知道实际授权状态之前开始位置更新,因此我将提供一个完整的解决方案,就像我会做的那样。随时问是否有不清楚的地方:
class ViewController: UIViewController {
var latitude: CLLocationDegrees?
var longitude: CLLocationDegrees?
lazy var locationManager: CLLocationManager = {
let locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
return locationManager
}()
@IBAction func getLocation(_ sender: UIBarButtonItem) {
locationManager.delegate = self
checkAuthorizationStatus()
}
private func checkAuthorizationStatus(_ status: CLAuthorizationStatus? = nil) {
switch status ?? CLLocationManager.authorizationStatus() {
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .authorizedWhenInUse:
locationManager.startUpdatingLocation()
default:
showLocationDisabledPopUp()
}
}
func showLocationDisabledPopUp() {
// your popup code
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// your segue code
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
checkAuthorizationStatus(status)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last, location.horizontalAccuracy > 0 else { return }
manager.delegate = nil
manager.stopUpdatingLocation()
latitude = location.coordinate.latitude
longitude = location.coordinate.longitude
performSegue(withIdentifier: "toLocal", sender: nil)
}
}
答案 1 :(得分:0)
这里的问题是您要在其中进行搜索
const x = [1,2,3]
let results = []
async function getAsyncResults(array){
// map returns an array, this time, an array of promises
const promises = x.map(number => someAsyncJobLikeADatabaseCall(number))
// Promise.all resolves, if all promises in the array have been resolved
return Promise.all(promises)
}
try {
let results = await getAsyncResults(x)
// this will return the results you expect.
console.log(results)
} catch (err) {
console.log('Some error', err)
}
可以多次触发的(每次新位置都来自func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
时)。有几种方法可以解决此问题,但是为了使您的更改尽可能少,我建议这样做:
CLLocationManager
让我知道是否有帮助,否则我们可以再更改一些代码来解决此简单问题。
编辑:如此您便知道:最好在其中执行segue
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[locations.count - 1]
if location.horizontalAccuracy > 0 {
locationManager.stopUpdatingLocation()
latitude = location.coordinate.latitude
longitude = location.coordinate.longitude
}
let status = CLLocationManager.authorizationStatus()
switch status {
case .restricted, .denied:
showLocationDisabledPopUp()
return
case .notDetermined:
// Request Access
locationManager.requestWhenInUseAuthorization()
case .authorizedAlways:
print("Do Nothing: authorizedAlways")
case .authorizedWhenInUse:
//-- MODIFIED HERE --
locationManager.stopUpdatingLocation()
locationManager = nil
Dispatch.main.async {
self.performSegue(withIdentifier: "toLocal", sender: nil)
}
}
}
根据您的需要状态为private func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus)
或kCLAuthorizationStatusAuthorized
或kCLAuthorizationStatusAuthorizedAlways
时。