简体   繁体   中英

Update location when user is in background - swift

I've had an issue for like 3-4 months. I've tried everything you can ever imagine to get this to work, but I really can't. Now I'm looking for your help to fix this issue.

I've an application, when you press a start button it should get locations. (Works perfectly fine when ur on the application.) But once you leave the application, (not killing the process) and goes to the background. The polyline is not drawing like it should. It pauses or something.

I need someone either who can help me here, or create a chatroom with me so we can discuss and I will send the rest of the code.

Here is parts of it, which I think is the most important. Inside the viewDidLoad

 let app = UIApplication.shared

        NotificationCenter.default.addObserver(self, selector: #selector(applicationWillResignActive(notification:)), name: UIApplication.willResignActiveNotification, object: app)

        NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive(notification:)), name: UIApplication.didBecomeActiveNotification, object: app)

-

 @objc func applicationWillResignActive(notification: NSNotification)
    {
        start = CFAbsoluteTimeGetCurrent()
        print("Background entered")
        startReceivingSignificantLocationChanges()

    }

    @objc func didBecomeActive(notification: NSNotification)
    {
        let elapsed = CFAbsoluteTimeGetCurrent() - start
        counter = counter + Int(elapsed)
        print("Returned to application")
        locationManager.stopMonitoringSignificantLocationChanges()

    }

< Inside the start button.

//Checking userpermission to allow map and current location
            if (CLLocationManager.locationServicesEnabled())
            {
                locationManager.requestAlwaysAuthorization()
                locationManager.requestWhenInUseAuthorization()

                self.locationManager.allowsBackgroundLocationUpdates = true
                self.locationManager.showsBackgroundLocationIndicator = true

                //Retrieve current position
                if let userLocation = locationManager.location?.coordinate
                {
                    //Zooming in to current position
                    let viewRegion = MKCoordinateRegion(center: userLocation, latitudinalMeters: 200, longitudinalMeters: 200)
                    mapView.setRegion(viewRegion, animated: false)

                    //Creating a start annotation
                    if locations.isEmpty
                    {
                        let annotation = MKPointAnnotation()
                        annotation.title = "Start"
                        annotation.coordinate = userLocation
                        mapView.addAnnotation(annotation)
                    }

                    self.locations.append(userLocation)
                    print(self.locations, "First")

                    //Starts the walk-timer, with interval: 1 second
                    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)

                    //Sending to update
                    update()
                }
            }

< Background worker

func startReceivingSignificantLocationChanges()
    {
        let authorizationStatus = CLLocationManager.authorizationStatus()
        if authorizationStatus != .authorizedAlways
        {
            return
        }

        if !CLLocationManager.significantLocationChangeMonitoringAvailable()
        {
            // The service is not available.
            return
        }
        else
        {
            locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
            locationManager.distanceFilter = 100.0 //100.0 meters
            locationManager.activityType = .fitness
            locationManager.allowsBackgroundLocationUpdates = true
            locationManager.delegate = self
            locationManager.startMonitoringSignificantLocationChanges()
        }
    }

    func locationManager(_ manager: CLLocationManager,  didUpdateLocations
        locations: [CLLocation])
    {
        let lastLocation = locations.last!

        self.locations.append(lastLocation.coordinate)

        print("Locations retrieved from background: ", self.locations)
    }

There is a lot more I've to show you. But unfortunately it would be way too much...

Please enable the Background Modes from the capabilities of the project and enable the 'Location updates'. After enabling this, the only configuration to get the updates in the background(not in killed state) is to set'allowsBackgroundLocationUpdates' to true(which you have done already).

Here the significant location changes are only needed when you want to get the location when the application is killed by the user. This significant location change will launch the application in background and read the location of the device. For more information on getting location in the background follow :

https://developer.apple.com/documentation/corelocation/cllocationmanager/1620568-allowsbackgroundlocationupdates

For significant location changes while the application is in killed state, follow below link. This is in objective C but it can be easily done in swift also.

http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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