【问题标题】:CLLocationManager is asynchronous. Having problems with thisCLLocationManager 是异步的。有这个问题
【发布时间】:2019-03-19 20:42:40
【问题描述】:

我做的很简单。

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() 仅被调用一次(具有正确的位置) ,然后在此之后连续调用该位置,因为我将有另一种方法使用它。

我不确定如何实现。

【问题讨论】:

    标签: ios swift asynchronous cllocation


    【解决方案1】:

    来自documentation for didUpdateLocations

    位置

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

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

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let location = locations.last {
            currentLocation = location
        }
    }
    

    如果你希望fetchHomeFeed 只在有几个选项时被调用,但最简单的是在调用它之前检查一个布尔标志,并在第一次调用它时更改它。

    【讨论】:

    • 我只是在你给我的 if 语句中包含了我的 for 循环、一个布尔值和 fetchHomeFeed()。非常感谢!感谢您的帮助:)
    • 我还需要不断更新位置,以防用户在车内或其他地方
    • 我怀疑这样做是否有用——如果碰巧同时有多个更新,那么 for 循环会很快通过它们,以至于除了最后一个之外,它对任何其他东西都没有用。如果用户在汽车中旅行,则系统将在他们的位置发生变化时发送离散的位置更新,这由位置管理器的设置确定。请注意,您还可以指定 desired accuracy and distance filter 以确保以您喜欢的频率获取更新(尽管默认值可能适合您)。
    • 虽然为了准确起见,kCLLocationAccuracyBestForNavigation 可能是您想要的,而不是默认值(尽管他们建议仅在插入设备时使用它)但是为了用户的电池,我会仔细考虑您是否真的需要如此频繁的位置更新。
    • 该方法的locations参数中的其他位置是,例如,如果您关心用户的位置历史记录,例如在地图上跟踪您的路线的应用程序。跨度>
    【解决方案2】:

    从 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()
            }
        }
    

    【讨论】:

    • 这对我的问题的第一部分很有效,谢谢.. 我只需要在此之后继续获取位置。
    猜你喜欢
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2020-06-02
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2017-08-02
    相关资源
    最近更新 更多