用户授权位置使用时出现双重欺诈行为

时间:2018-12-19 11:44:09

标签: ios swift segue cllocationmanager

在我的iOS应用程序中,我正在请求用户获得设备位置的权限。在我的主ViewController上,我有一个导航栏按钮,在点击该按钮时,它将询问用户使用许可。如果用户点击“确定”,它将被发送到显示本地数据的视图控制器。如果用户点击取消,则什么也不会发生。我还会弹出一个窗口,提示用户何时以及是否再次轻按“位置”按钮,以将其重定向到设置以授权位置设置(如果先前已取消的话)。

该应用程序可以按照我在模拟器中的预期运行,但是当在设备上使用时,当用户点击“确定”以允许位置使用时,它会选择连接到本地View Controller,但它连续进行了2到3次。

segue从主视图控制器转到本地视图控制器,并使用IBAction从按钮点击请求权限。

位置信息在主视图控制器中获得,并传递给本地控制器。本地控制器按预期显示所有内容。

如何防止对同一个View Controller进行这种双重或三次选择?

下面是我的代码:

SELECT * FROM address WHERE address REGEXP '[[:<:]]demo[[:>:]]' AND 'demo' REGEXP '[0-9]'

2 个答案:

答案 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) kCLAuthorizationStatusAuthorizedkCLAuthorizationStatusAuthorizedAlways时。