SWIFT - LocationManager循环多次? [英] SWIFT - LocationManager looping through multiple times?

查看:157
本文介绍了SWIFT - LocationManager循环多次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个locationManager功能来获取用户当前位置并发布城市和州的名称。我有一个打印声明,所以我可以在我的控制台检查一切是否正常工作......事实确实如此。但是,它打印城市位置3次。这实际上在我的实际应用中引起了一个问题,但这超出了这个问题的范围。

I have a locationManager function to grab the users current location and posting the name of the city and state. I have a print statement so I can check in my console if everything is working properly...and it is. However, it prints the city location 3 times. This actually causes an issue in my actual app but thats beyond the point of this question.

我的功能如下:

var usersLocation: String!

var locationManager: CLLocationManager!

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let userLocation: CLLocation = locations[0]


    CLGeocoder().reverseGeocodeLocation(userLocation) { (placemarks, error) -> Void in

        if error != nil {

            print(error)

        } else {

            let p = placemarks?.first // ".first" returns the first element in the collection, or nil if its empty
            // this code above will equal the first element in the placemarks array

            let city = p?.locality != nil ? p?.locality : ""
            let state = p?.administrativeArea != nil ? p?.administrativeArea : ""

            self.navigationBar.title = ("\(city!), \(state!)")
            self.usersLocation = ("\(city!), \(state!)")
            self.locationManager.stopUpdatingLocation()
            print(self.usersLocation)
            self.refreshPosts()
        }
    }
}

所以在我的打印(self.usersLocation)中它会打印出来我的控制台三次。这是正常的吗?

So in my print(self.usersLocation) it will print in my console three times. Is this normal?

更新显示视图

override func viewDidLoad() {
    super.viewDidLoad()

    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()

    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.estimatedRowHeight = 250.0
}


推荐答案

我首先建议一些事情:


  1. 致电 stopUpdatingLocation 在执行 reverseGeocodeLocation 之前。

您正在调用 stopUpdatingLocation reverseGeocodeLocation 完成处理程序关闭内。问题是它以异步方式运行,因此 didUpdateLocations 可能会在此期间收到其他位置更新。通常,当您第一次启动位置服务时,您将获得许多更新,通常会提高准确性(例如 horizo​​ntalAccuracy 越来越小的值)。如果在启动异步地理编码请求之前关闭位置服务,则可以最大限度地减少此问题。

You are calling stopUpdatingLocation inside the reverseGeocodeLocation completion handler closure. The problem is that this runs asynchronously, and thus didUpdateLocations may receive additional location updates in the intervening period. And often, when you first start location services, you'll get a number of updates, often with increasing accuracy (e.g. horizontalAccuracy values that are smaller and smaller). If you turn off location services before initiating asynchronous geocode request, you'll minimize this issue.

您还可以添加添加 distanceFilter 在 viewDidLoad 中,这将最大程度地减少对委托方法的冗余调用:

You can also add add a distanceFilter in viewDidLoad, which will minimize redundant calls to the delegate method:

locationManager.distanceFilter = 1000


  • 您可以使用自己的州检查反向地理编码过程是否已启动的变量。例如:

  • You can use your own state variable that checks to see if the reverse geocode process has been initiated. For example:

    private var didPerformGeocode = false
    
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        // if we don't have a valid location, exit
    
        guard let location = locations.first where location.horizontalAccuracy >= 0 else { return }
    
        // or if we have already searched, return
    
        guard !didPerformGeocode else { return }
    
        // otherwise, update state variable, stop location services and start geocode
    
        didPerformGeocode = true
        locationManager.stopUpdatingLocation()
    
        CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
            let placemark = placemarks?.first
    
            // if there's an error or no placemark, then exit
    
            guard error == nil && placemark != nil else {
                print(error)
                return
            }
    
            let city = placemark?.locality ?? ""
            let state = placemark?.administrativeArea ?? ""
    
            self.navigationBar.title = ("\(city), \(state)")
            self.usersLocation = ("\(city), \(state)")
            print(self.usersLocation)
            self.refreshPosts()
        }
    }
    


  • 这篇关于SWIFT - LocationManager循环多次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆