简体   繁体   English

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

[英]Keeping track of time in background to handle location updates

I have two constraints in my app, one is user location and the other one is time. 我的应用程序有两个约束,一个是用户位置,另一个是时间。 Following is the simple location implementation. 以下是简单的位置实现。

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

With this code, I expect to get triggered every time the user location changes by 20m (in background as well). 使用此代码,我希望每次用户位置变化20m时(在后台)也会被触发。 However, I also need to track the time the user stays in a particular location. 但是,我还需要跟踪用户停留在特定位置的时间。 Since i need to track the background case, I cannot use timer. 由于我需要跟踪背景情况,因此无法使用计时器。

I followed https://www.raywenderlich.com/143128/background-modes-tutorial-getting-started to try background task but as stated in the article, the background time allowed that I got was around 3 min (which is variable). 我按照https://www.raywenderlich.com/143128/background-modes-tutorial-getting-started尝试进行后台任务,但是如文章所述,后台时间允许我大约3分钟(这是可变的) 。 So i believe I cannot go with this. 所以我相信我不能这样做。

How can I solve this? 我该如何解决?

EDIT: I also need to make an api call if the user stays in a location for X minutes. 编辑:如果用户在某个位置停留X分钟,我还需要进行api调用。 So for that case, it would not be feasible to wait for location updates and calculate the time differences. 因此,在这种情况下,等待位置更新并计算时间差是不可行的。 I could previously solve this by removing the distance filter and continuously checking the location and comparing the time and location. 我以前可以通过删除距离过滤器并连续检查位置并比较时间和位置来解决此问题。 I guess continuous location tracking will get the app rejected, that's why I went for filter. 我猜想连续的位置跟踪将使应用程序被拒绝,这就是为什么我选择过滤器。 But i am not sure if it will still get rejected or not since iOS will need to track the location for filter as well. 但是我不确定它是否仍然会被拒绝,因为iOS也需要跟踪过滤器的位置。

You can use simple Date objects to track the time spent between location updates even if your app is in the background. 您可以使用简单的Date对象来跟踪两次位置更新之间花费的时间,即使您的应用程序处于后台。 Simply declare a Date property for your class, update its value from func locationManager(_:, didUpdateLocations:) and compare that to the current time. 只需为您的类声明一个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
}

Response to the question edit: making an API call after X minutes have passed in the background without a location update is not possible, since there's no supported background mode for executing arbitrary functions at specific points in time. 对问题编辑的回答:在后台经过X分钟后无法进行API调用而没有位置更新是不可能的,因为不支持在特定时间执行任意功能的后台模式。 Getting rid of the distance filter as you explained in your edit could be a valid alternative, however if your app is only using location updates to be able to make the API calls and isn't actually doing anything with those locations, your app might indeed get rejected. 如您在编辑中所述,摆脱距离过滤器可能是一个有效的选择,但是,如果您的应用仅使用位置更新来进行API调用,而实际上并没有对这些位置执行任何操作,则您的应用可能确实被拒绝。

When you receive a new location update, check the time difference from the previous update.. giving you the time that they were at the last location. 当您收到新的位置更新时,请检查与前一个更新的时差..为您提供它们在最后一个位置的时间。

Depending on what you are doing with these location updates, this might just be pulling the latest update from some DB, or posting to an API. 根据您对这些位置更新的处理方式,可能只是从某些数据库中获取最新更新,或者发布到API。

An example.. 一个例子..

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM