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

Posted

技术标签:

【中文标题】如何从位置管理器只复制一次用户位置?【英文标题】:How to copy user location only once from location manager? 【发布时间】:2021-01-20 23:24:04 【问题描述】:

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

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 Object 属性包装器和 State Object 属性包装器之间的区别。我的问题是 Observable Object 属性包装器允许我在视图中使用的变量不断变化,这在我的特定情况下不是我想要的。一旦我将其更改为状态对象,它就会完全按照我的意愿执行,即在位置更改时更新一次。

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

【问题讨论】:

【参考方案1】:

如果目标是了解我们的位置一次,则根本不要开始更新位置。相反,只需致电requestLocation。这将为您提供单个更新(在可能的延迟之后)。

【讨论】:

【参考方案2】:

你可以试试Publishers。下面是一个使用节流阀的未经测试的示例。

油门文档:

发布上游发布者在指定时间间隔内发布的最新或第一个元素。

// 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 = $0
        
    

要获得第一次更新,还有一种方法是.first()

【讨论】:

以上是关于如何从位置管理器只复制一次用户位置?的主要内容,如果未能解决你的问题,请参考以下文章

工作管理器的位置更新不起作用

您如何检测文件何时被放入 Windows 资源管理器?

如何从 Windows 任务管理器(应用程序选项卡)获取应用程序 + 从 Delphi 获取它们在 HDD 上的位置

如何查找任务管理器里的进程位置?

位置管理器提供的最新价值是啥

Swift 中的 CLLocation 管理器获取用户的位置