简体   繁体   English

CLLocationManager在后台时不更新,并获得混乱的位置坐标Swift

[英]CLLocationManager not updating while in background, and get messy location coordinates Swift

I have a tracking function but it doesn't update location while in background. 我具有跟踪功能,但是在后台时它不会更新位置。

1st case: Tracking while app is in the foreground -> the tracking is actually happening but doesn't get precise coordinates. 第一种情况:在应用程序处于前台时进行跟踪->跟踪实际上正在进行中,但没有获得精确的坐标。 I will change to locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation to see if improves accuracy of the tracking. 我将更改为locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation来查看是否提高了跟踪的准确性。

2nd case: Tracking while screen is off -> the tracking is a straight line from a to b, tracking doesn't update coordinates. 第二种情况:屏幕关闭时跟踪->跟踪是从a到b的直线,跟踪不会更新坐标。

3rd case: Tracking while app is in back ground(pressed home button) -> tracking is happening as case 1. 第三种情况:在应用程序处于后台(按下主页按钮)时进行跟踪->与情况1一样发生跟踪。

I found a post that explains that if authorisation is set to always you have to specify you want to keep updating location while in background, but nothing has changed. 我发现有一篇帖子解释说,如果将授权设置为始终,则必须指定要在后台继续更新位置,但是没有任何变化。 This is the code and info.plist : 这是代码和info.plist:

override func viewDidLoad() {
        super.viewDidLoad()


        mapView.delegate = self
        locationManager.delegate = self
//        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
//        locationManager.allowsBackgroundLocationUpdates = true  //for getting user location in background mode as well

        mapView.showsUserLocation = true
        mapView.userTrackingMode = .follow   //map following user                    

        configureLocationServices()
        addDoubleTap() // enabling duble tap gesture recognizer
//        mapView.isUserInteractionEnabled = true

        let location = locationManager.location?.coordinate
        let region = MKCoordinateRegionMakeWithDistance(location!, 1000, 1000) // set mapView based on user location coordinates
        mapView.setRegion(region, animated: true)
        centerMapOnLocation()

        // alerts coordinates to post to Firebase
        let alertDrawLatitude =  alertDrawCoordinates?.latitude  // not used ?
        let alertDrawLomgitude = alertDrawCoordinates?.longitude
        let title: String? = alertNotificationType
        var subtitle: String? = alertNotificationType

        //  user alert notification. takes coordinates from alertNotificationArray( populated with firebase returning coordinate for all alerts

         displayAlerts()
    }            

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let mostRecentLocation = locations.last else { return }        
        self.actualRouteInUseCoordinatesArray.append(mostRecentLocation.coordinate)

    }            

    func configureLocationServices() {
            if authorizationStatus == .notDetermined{
                locationManager.requestAlwaysAuthorization()
            } else if authorizationStatus == .authorizedAlways {
            locationManager.showsBackgroundLocationIndicator = true //set update location even if in background. very imposrtant!!
          }
        }

info.plist中

UPDATE: 更新:

changing the accuracy only made things worse. 更改精度只会使情况变得更糟。

with AccuracyBest: AccuracyBest: 精度最高

and with AccuracyBestForNAvigation 并使用AccuracyBestForNAvigation

最适合导航的精度

second tracking is actually worse.. how can navigation apps rely on this kind of tracking? 第二次跟踪实际上更糟..导航应用程序如何依靠这种跟踪? is there anything wrong with my code for LocationManager? 我的LocationManager代码有什么问题吗?

SECOND UPDATE: it now get updated location when in background, but is way off..I never passed the yellow street and it shows like I waked for 10 minutes after it.. 第二次更新:现在,它在后台时会获得更新的位置,但是距离很远。.我从未经过黄色的街道,并且它显示出它醒来10分钟后的样子。

THIRD EDIT: 第三编辑:

I found out that I should filter out GPS raw data, so I'm using a Kalman filter, and it really smooths out the resulting tracking. 我发现我应该过滤掉GPS原始数据,所以我使用的是卡尔曼过滤器,它确实可以平滑结果跟踪。 So I'm fine tuning two parameters, and in order to be able to change those parameters I added two textfields @IBOutlet weak var filterValueTextField: UITextField! 因此,我微调了两个参数,为了能够更改这些参数,我添加了两个文本字段@IBOutlet weak var filterValueTextField: UITextField! and @IBOutlet weak var horizontalAccuracyTextField: UITextField! @IBOutlet weak var horizontalAccuracyTextField: UITextField! and connected those to the parameters 并将它们连接到参数

hcKalmanFilter?.rValue = Double(String( describing:filterValueTextField?.text!))! and guard mostRecentLocation.horizontalAccuracy < Double(String( describing: horizontalAccuracyTextField?.text!))! else { return } guard mostRecentLocation.horizontalAccuracy < Double(String( describing: horizontalAccuracyTextField?.text!))! else { return } guard mostRecentLocation.horizontalAccuracy < Double(String( describing: horizontalAccuracyTextField?.text!))! else { return } . guard mostRecentLocation.horizontalAccuracy < Double(String( describing: horizontalAccuracyTextField?.text!))! else { return } My problem is now that it finds nil while unwrapping value in the horizontalAccuracy parameter. 我的问题是,当在horizo​​ntalAccuracy参数中解包值时,它会找到nil。 If in horizontalAccuracy I just put a value it accepts an integer, but when I take it from the texField converting the textfield.text to Int, compiler throws an error Binary operator '<' cannot be applied to operands of type 'CLLocationAccuracy' (aka 'Double') and 'Int' , while if I convert it to Double doesn't, but it finds nil. 如果在horizo​​ntalAccuracy中我只是放置了一个值,它接受一个整数,但是当我从将textfield.text转换为Int的texField中获取它时,编译器将引发错误Binary operator '<' cannot be applied to operands of type 'CLLocationAccuracy' (aka 'Double') and 'Int' ,而如果我将其转换为Double则不会,但是它会找到nil。 Why the filterValue finds a value from it's textField, and the horizontal Accuracy doesn't? 为什么filterValue从它的textField中找到一个值,而水平Accuracy却找不到? they're declared, and use the same way. 它们被声明,并且使用相同的方式。 Any idea? 任何想法?

游走了

First of all you have limited time while your app goes to background, and that time is depend upon load on your device's OS, but most probably it is approx. 首先,您的应用程序进入后台运行的时间有限,该时间取决于设备操作系统的负载,但最可能的时间约为。 30 seconds. 30秒。 So this is the reason your are not getting location updates while your screen is off or while your app goes to background. 因此,这就是在屏幕关闭或应用程序进入后台时无法获取位置更新的原因。

But Apple allows app to run in background for some tasks and location update is one of them, so you can fetch location updates even if your app goes to background by enabling Background Fetch capability for your app. 但是Apple允许应用程序在某些任务在后台运行,位置更新就是其中之一,因此,即使您的应用程序进入后台,也可以通过为应用程序启用Background Fetch功能来获取位置更新。

For more details please follow below official doc. 有关更多详细信息,请遵循以下官方文档。 of Apple: 苹果:

https://developer.apple.com/documentation/corelocation/getting_the_user_s_location/handling_location_events_in_the_background https://developer.apple.com/documentation/corelocation/getting_the_user_s_location/handling_location_events_in_the_background

And secondly try to maintain your locationmanager object in global scope of your app like you can place it in AppDelegate or in Singleton class if you are maintaining any for your app, so it will always be available. 其次,尝试维护您的应用程序的全局范围内的locationmanager对象,例如,如果您要为应用程序维护任何对象,则可以将其放置在AppDelegate或Singleton类中,因此它将始终可用。

Sometimes location that you receive does not have desired accuracy, especially when you've just started tracking, first couple of locations are going to be well off. 有时,您收到的位置信息并没有理想的准确性,尤其是当您刚刚开始跟踪时,前几个位置信息会很不理想。 You can use location's horizontal accuracy property to filter location witch have, for example, less then 50m accuracy 您可以使用位置的水平精度属性来过滤位置精度不超过50m的位置

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

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