跟踪后台时间以处理位置更新

时间:2018-06-14 09:56:19

标签: ios swift timer location

我的应用程序中有两个约束,一个是用户位置,另一个是时间。以下是简单的位置实现。

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*******")
}

使用此代码,我希望每次用户位置更改20米时都会触发(在后台也是如此)。但是,我还需要跟踪用户在特定位置停留的时间。由于我需要跟踪背景情况,我不能使用计时器。

我跟着https://www.raywenderlich.com/143128/background-modes-tutorial-getting-started尝试后台任务,但正如文章所述,我得到的后台时间大约是3分钟(这是可变的)。所以我相信我不能这样做。

我该如何解决这个问题?

编辑:如果用户在某个位置停留X分钟,我还需要拨打api电话。因此,对于这种情况,等待位置更新并计算时间差是不可行的。我之前可以通过移除距离过滤器并连续检查位置并比较时间和位置来解决这个问题。我想连续位置跟踪会让应用程序被拒绝,这就是我去过滤器的原因。但我不确定它是否会被拒绝,因为iOS也需要跟踪过滤器的位置。

2 个答案:

答案 0 :(得分:1)

即使您的应用位于后台,您也可以使用简单的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调用而实际上并未对这些位置执行任何操作,那么您的应用可能确实如此被拒绝。

答案 1 :(得分:0)

当您收到新的位置更新时,请检查与之前更新的时差。为您提供他们在最后一个位置的时间。

根据您对这些位置更新的处理方式,这可能只是从某个数据库中提取最新更新,或者发布到API。

一个例子..

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    print("*******Location updated*******")
    let lastUpdateDate = // get the last datetime you received information

    let currentDate = Date()
    let minutesDifference = let componentsLeftTime = Calendar.current.dateComponents([.minute], from: lastUpdateDate, to: currentDate)
}