我的应用程序有两个约束,一个是用户位置,另一个是时间。以下是简单的位置实现。
func determineMyCurrentLocation() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.allowsBackgroundLocationUpdates = true
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestAlwaysAuthorization()
locationManager.distanceFilter = 20
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("*******Location updated*******")
}
有了这段代码,我希望每次用户位置改变 20m(在后台也是如此)时都会被触发。但是,我还需要跟踪用户在特定位置停留的时间。因为我需要跟踪背景案例,所以我不能使用计时器。
我关注了https://www.raywenderlich.com/143128/background-modes-tutorial-getting-started尝试后台任务,但如文章所述,后台时间允许我得到大约 3 分钟(这是可变的)。所以我相信我不能接受这个。
我该如何解决这个问题?
编辑:如果用户在某个位置停留 X 分钟,我还需要进行 api 调用。所以对于那种情况,等待位置更新并计算时间差是不可行的。我以前可以通过移除距离过滤器并不断检查位置并比较时间和位置来解决这个问题。我想持续的位置跟踪会让应用程序被拒绝,这就是我选择过滤器的原因。但我不确定它是否仍会被拒绝,因为 iOS 也需要跟踪过滤器的位置。
最佳答案
您可以使用简单的 Date
对象来跟踪位置更新之间花费的时间,即使您的应用程序在后台也是如此。只需为您的类声明一个 Date
属性,从 func locationManager(_:, didUpdateLocations:)
更新它的值并将其与当前时间进行比较。
// Declare this in a scope that can be accessed from `didUpdateLocations` and where its value won't be released from memory
var lastUpdateTimestamp = Date()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let now = Date()
let timeSinceLastUpdate = now.timeIntervalSince(lastUpdateTimestamp)
print("\(timeSinceLastUpdate) seconds passed since last location update")
lastUpdateTimestamp = now
}
对问题编辑的回应:X 分钟后在后台进行 API 调用而不进行位置更新是不可能的,因为不支持在特定时间点执行任意函数的后台模式。正如您在编辑中解释的那样摆脱距离过滤器可能是一个有效的选择,但是如果您的应用仅使用位置更新来进行 API 调用并且实际上没有对这些位置执行任何操作,那么您的应用可能确实被拒绝。
关于ios - 在后台跟踪时间以处理位置更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50854677/