swift - 不断检索到目的地 MapKIt 的时间
问题描述
我的目标是有两个用户,其中一个步行/骑自行车/开车走向另一个,让另一个用户检查另一个用户到达的剩余时间和距离。为了实现这一点,我目前正在使用 FIR 实时数据库。
我想我可以使用 MKDirections.Request 来计算剩余时间。但当然是我实现它的方式:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
directionsRequest.source = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: coordinates.latitude, longitude: coordinates.longitude), addressDictionary: nil))
directionsRequest.destination = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: destination.latitude, longitude: destination.longitude), addressDictionary: nil))
let directions = MKDirections(request: directionsRequest)
var approxTime: Double = 9999
directions.calculate { [self] (response, error) -> Void in
guard let response = response else {
if let error = error {
print("Error: \(error)")
}
return
}
if response.routes.count > 0 {
let route = response.routes[0]
approxTime = route.expectedTravelTime
}
}
}
}
其中方向请求被定义为
let directionsRequest: MKDirections.Request = MKDirections.Request()
init() {
directionsRequest.requestsAlternateRoutes = true
directionsRequest.transportType = .automobile
}
正如您可能想象的那样,在最大化请求尝试一段时间后,此实现会失败,并返回以下错误
Error: Error Domain=MKErrorDomain Code=3 "Directions Not Available" UserInfo={NSLocalizedFailureReason=Route information is not available at this moment., MKErrorGEOError=-3, MKErrorGEOErrorUserInfo={ details = ( { intervalType = short; maxRequests = 50; " throttler.keyPath" = "app:someapp/0x20200/short(default/any)"; timeUntilReset = 31; windowSize = 60; } ); timeUntilReset = 31; }, MKDirectionsErrorCode=3, NSLocalizedDescription=方向不可用}
我可以将对该函数的调用限制为每 5 秒一次,但是看到苹果限制了请求,我认为我在这里的路径不正确。有没有更好的方法来实现这一点?也许还有一些我没能找到的其他对象/功能
SN:目前使用 SwiftUI 5.5
编辑:我添加这个小评论来澄清它,问题是
directions.calculate
不能多次调用,我认为每 30 秒有 50 个请求。但是其他用户在实时数据库上每秒左右更新一次位置,所以这意味着每 1 秒进行一次计算,这会最大化计算请求。
解决方案
在我看来,最好的方法是使用内置实时更新功能的 Firestore 来解决。Google 提供了一个看起来像这样的示例代码段。https://firebase.google.com/docs/firestore/query-data/listen#swift
db.collection("cities").document("SF")
.addSnapshotListener { documentSnapshot, error in
guard let document = documentSnapshot else {
print("Error fetching document: \(error!)")
return
}
guard let data = document.data() else {
print("Document data was empty.")
return
}
print("Current data: \(data)")
}
本质上,这里发生的事情是每次SF
更新文档时,都会在该闭包中触发一个新快照。它特别酷的地方在于,您可以使用它来通知接收方数据库的更新。因此,您还希望将文档配置为具有一些字段lat
和long
快照侦听器正在监视这些更新的一些字段。发生更新时,请计算您的距离。这样做,您只需要在数据库上创建新值时进行计算,您还可以限制应用程序向数据库创建新值的频率。您需要做的就是确保每个人都在查看具有您期望值的正确文档。
另一个提示是让两个用户都向同一个文档报告。如果你这样做,它会变得更加容易,因为 snapshotListener 将首先监听本地更改,允许你在写入文档的任何时候计算你的距离,然后当收到它时,另一方也可以得到他们的更新。你的可能看起来像这样。
db.collection("yourTripIdentifer").document("yourGroupIdentifier")
.addSnapshotListener { documentSnapshot, error in
guard let document = documentSnapshot,
let data = document.data() else { return }
//We have data, let's use it.
calculateDistance(from: data)
}
推荐阅读
- javascript - classycountdown.js 上的固定日期
- javascript - 如何禁用 HTML/JS 中的样式元素?
- c# - InvalidOperationException:未指定 authenticationScheme,在 ASP.NET Core 2.0 中未找到 DefaultChallengeScheme
- msbuild - 在 MSBuild 中构建混合 .Net Standard 和 .NetFramework 解决方案
- asp.net - 域更改后 20 分钟的 SessionState
- c# - 在没有数组或任何循环的情况下从用户那里获取 5 个值并找到最大值和最小值
- azure - 天蓝色。手动触发时释放未触发并卡住
- python - TensorFlow Serving:在运行时更新 model_config(添加其他模型)
- python - 如何按值解析 argparser 参数
- magento2 - Magento2 您必须使用 --with-jpeg-dir=DIR 选项安装 GD 库