CLLocationManager是异步的。有这个问题

时间:2019-03-19 20:42:40

标签: ios swift asynchronous cllocation

我正在做的事情很简单。

class HomeDatasourceController: UICollectionViewController, CLLocationManagerDelegate{
let locationManager:CLLocationManager = CLLocationManager()

//CurrentLocation is my variable that isn't changing on time
var currentLocation = CLLocation(latitude: 5.0, longitude: 5.0)

override func viewDidLoad() {
    super.viewDidLoad()


    locationManager.delegate = self
    locationManager.requestAlwaysAuthorization()
    self.locationManager.startUpdatingLocation()


    fetchHomeFeed()
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    for currentLocationTemp in locations {
        self.currentLocation = currentLocationTemp
        print("This is latitude: \(currentLocation.coordinate.latitude) , and this is longitude: \(currentLocation.coordinate.longitude)")
    }
}
fetchHomeFeed(){
    print("Hello: ", self.currentLocation)
}

调用fetchHomeFeed时,它仅打印出我设置为(5.0纬度和经度)的虚拟位置,而不是我的实际位置。 我知道这是异步的,但我不确定至少第一次如何获得呼叫,以便我可以正确打印出我的位置(第一次)。

此后,我还需要它继续更新,因为我想实时更新用户的位置。

我曾尝试在func locationManager中使用fetchHomeFeed(),但这多次打印出来(“ Hello:”,self.currentLocation),我只希望fetchHomeFeed()仅被调用一次(具有正确的位置) ,然后连续调用该位置,因为我将使用另一种方法。

我不确定如何实现。

2 个答案:

答案 0 :(得分:0)

documentation for didUpdateLocations

  

位置

     

包含位置数据的CLLocation对象数组。该数组始终包含至少一个表示当前位置的对象。如果更新被推迟,或者在交付之前到达多个位置,则阵列可能包含其他条目。数组中的对象按照它们发生的顺序进行组织。因此,最近的位置更新位于阵列的末尾。

因此,您不需要遍历位置数组,只需使用.Left,除非您的应用程序需要担心推迟的位置更新。

locations.last

如果您只想一次调用func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let location = locations.last { currentLocation = location } } ,则有多个选项,但最简单的方法是在调用布尔型标志之前对其进行检查,并在首次调用它时对其进行更改。

答案 1 :(得分:0)

从viewDidLoad中删除fetchHomeFeed。这是不对的。

在locationManager函数中执行此操作。这将确保您具有有效的位置。获得有效位置后,您将停止位置管理器,然后根据需要重新启动。如果要连续监视位置,则需要重新考虑解决方案,但这将为您提供一个思路。

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

        guard let location = locations.last else {
               return
        }

        if location.horizontalAccuracy > 0 {
             locationManager.stopUpdatingLocation()
             locationManager.delegate = nil
             fetchHomeFeed()
        }
    }