如何从位置管理器中仅复制一次用户位置?

How to copy user location only once from location manager?

我在位置管理器 class 中有一个函数可以获取用户的当前位置坐标。对于我在另一个视图中的使用,它更新得太频繁了。我正在尝试想出一种方法来减少获取位置的频率或次数有限,但一直无法想出任何办法。我的猜测是它需要时间戳或我不熟悉的这种方法。非常感谢任何帮助。

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

    // self.location = location does the copying here too frequently
    self.location = location
    
    self.reverseGeocode()
}

解决方案:

经过反复试验,解决方案最终成为 Observable 对象 属性 包装器和状态对象 属性 包装器之间的区别。我的问题是 Observable Object 属性 包装器允许我在我的视图中使用的变量不断变化,这不是我在特定情况下想要的。一旦我将它更改为状态对象,它就会完全按照我的意愿进行操作,即在位置更改时更新一次。

对于那些感兴趣的人,这里有一个很好的博客 post 概述了这些主要区别: https://www.donnywals.com/whats-the-difference-between-stateobject-and-observedobject/.

如果目标是了解一次我们的位置,则根本不要开始更新位置。相反,只需调用 requestLocation。这会给你一个更新(在可能的延迟之后)。

你可以试试Publishers。下面是一个使用油门的未经测试的示例。

节流文档:

Publishes either the most-recent or first element published by the upstream publisher in the specified time interval.

// Setup:
let locationPublisher = PassthroughSubject<CGFloat, Never>()

// Send updates.
locationPublisher.send(value)

// Update only every x seconds.
struct MyView {
    @State var location: CGFloat? = nil
    var body: some View {
        Text("Value: \(location)")
        .onReceive(
            locationPublisher
            .throttle(for: 1.0, scheduler: RunLoop.main, latest: true) {
        ){
            self.location = [=10=]
        }
    }
}

要仅获取第一个更新,还有一种方法 .first()