代码之家  ›  专栏  ›  技术社区  ›  fs_tigre

使用locationmanager时最小化对服务器的HTTP请求

  •  1
  • fs_tigre  · 技术社区  · 6 年前

    在下面的代码中,我使用locationmanager获取用户当前的zipcode,然后向自己的服务器发出HTTP请求,以根据用户的zipcode获取一些数据。我的问题是我下面的代码每次都会发出HTTP请求 locationManager 通常每次呼叫三次。理想情况下,我只希望在找到最后一个位置标记后发出HTTP请求。

    如何最小化对自己服务器的HTTP请求?

    override func viewDidLoad() {
        super.viewDidLoad()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)-> Void in
            if error != nil {
                //AlertView to show the ERROR message
            }
            if placemarks!.count > 0 {
                let placemark = placemarks![0]
                var zipCode = placemark.postalCode ?? ""
                makeHTTPRequest(zipCode) // this is called 3 times
                self.locationManager.stopUpdatingLocation()
    
            }else{
                print("No placemarks found.")
            }
        })
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   nebuler    6 年前

    您的代码的问题是可能有多个调用 locationManager(_:didUpdateLocations:) 按你的时间堆积起来 self.locationManager.stopUpdatingLocation() . 为了解决这个问题:

    • 定义全局变量 var didFindZipCode: Bool = false .
    • 添加 guard didFindZipCode == false else { return } 在if块的开头检查放置标记的数目。
    • 集合 didFindZipCode = true 就在警卫声明之后。

    只需记住设置 didFindZipCode false 每当您想再次开始更新位置时。

        2
  •  1
  •   trndjc    6 年前

    问题是你的 CLGeocoder 方法异步返回,当它返回一个值时,您的位置管理器已经触发了多次。因此,只需在位置管理器第一次调用后停止更新位置,然后执行异步工作。

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    
        guard let location = locations.last else {
            return
        }
    
        // handle async work
        CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
    
            if let error = error {
                // alert with error
            } else if let placemarks = placemarks,
                placemarks.count > 0 {
                let placemark = placemarks[0]
                var zipCode = placemark.postalCode ?? ""
                makeHTTPRequest(zipCode)
            } else {
                print("No placemarks found.")
            }
    
        })
    
        locationManager.stopUpdatingLocation() // stop updating
    
    }
    

    顺便说一下,把你的 if-else 声明。如果你以 if ,您应该始终使用 else ,而不是用新的 如果 阻止。