Jord Adema
Jord Adema

Reputation: 281

Location manager stops updating location

enter image description hereI am having a problem while updating the user location. I am building app which is show the nearest trashcans and the distance between them and the user. I am using this locationmanager but it never updates the location. Even when the user moves, the stored locations stay the same

let manager = CLLocationManager()


func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {


    let location: CLLocation = locations.last!
    let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)

    //store myLocation in UserDefaults
    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.latitude, forKey: "latitude")
    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.longitude, forKey: "longitude")

    UserDefaults.standard.set(myLocation.latitude, forKey: "latitude")
    UserDefaults.standard.set(myLocation.longitude, forKey: "longitude")
    UserDefaults().synchronize()


    self.mapView.showsUserLocation = true

}

I am using this to calculate the distance

let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.value(forKey: "latitude") as! CLLocationDegrees, UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.value(forKey: "longitude") as! CLLocationDegrees)



    // geeft zin met afstand van locatie1 tot myLocation
    func afstandPuntTotUser(locatie1: CLLocationCoordinate2D) -> String {
        manager.startUpdatingLocation()
        let cllocatie1 = converter(locatie: locatie1)
        let myLocation = converter(locatie: myLocation)
        let afstand = cllocatie1.distance(from: myLocation)
        let afgerondeafstand = afstand - afstand.truncatingRemainder(dividingBy: 1.0)                                   //zorgt voor 1 kommagetal
        if afstand < 1000.0 {
            return "De afstand tot de bak is \(afgerondeafstand) meter"
        }
        else {
            return "De afstand tot de bak is \(afgerondeafstand / 1000 - (afgerondeafstand / 1000).truncatingRemainder(dividingBy: 0.1)) kilometer"
        }
    }

inside the app this isn't a very big problem, but I need a constantly updated location in order for the widget to work properly. This widget shows the three nearest trashcans and doesn't really do what it is supposed to do if it is using old location data.

here is my complete ViewController:

 import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {



@IBOutlet weak var mapView: MKMapView!

let manager = CLLocationManager()


func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let location: CLLocation = locations[0]
    let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
    //let span: MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
    //let region: MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)

    //store myLocation in UserDefauls


    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.latitude, forKey: "latitude")
    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.longitude, forKey: "longitude")

    UserDefaults.standard.set(myLocation.latitude, forKey: "latitude")
    UserDefaults.standard.set(myLocation.longitude, forKey: "longitude")
    UserDefaults().synchronize()


    //region wel of niet? nog even over hebben
    //mapView.setRegion(region, animated: true)

    self.mapView.showsUserLocation = true
}





override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    manager.delegate = self
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.requestAlwaysAuthorization()
    manager.startUpdatingLocation()



    //maakt van CLLocationCoordinate een CLLocation
    func converter(locatie: CLLocationCoordinate2D) -> CLLocation {
        let latitude = locatie.latitude
        let longitude = locatie.longitude
        return CLLocation(latitude: latitude, longitude: longitude)
    }

    let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(UserDefaults.standard.value(forKey: "latitude") as! CLLocationDegrees, UserDefaults.standard.value(forKey: "longitude") as! CLLocationDegrees)

    //let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.value(forKey: "latitude") as! CLLocationDegrees, UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.value(forKey: "longitude") as! CLLocationDegrees)



    // geeft zin met afstand van locatie1 tot myLocation
    func afstandPuntTotUser(locatie1: CLLocationCoordinate2D) -> String {
        let cllocatie1 = converter(locatie: locatie1)
        let myLocation = converter(locatie: myLocation)
        let afstand = cllocatie1.distance(from: myLocation)
        let afgerondeafstand = afstand - afstand.truncatingRemainder(dividingBy: 1.0)                                   //zorgt voor 1 kommagetal
        if afstand < 1000.0 {
            return "De afstand tot de bak is \(afgerondeafstand) meter"
        }
        else {
            return "De afstand tot de bak is \(afgerondeafstand / 1000 - (afgerondeafstand / 1000).truncatingRemainder(dividingBy: 0.1)) kilometer"
        }
    }

    //geeft puur afstand van locatie1 tot myLocation
    func distanceForWidget(locatie1: CLLocationCoordinate2D) -> String {
        let cllocatie1 = converter(locatie: locatie1)
        let myLocation = converter(locatie: myLocation)
        let afstand = cllocatie1.distance(from: myLocation)
        let meters = afstand as Double - afstand.truncatingRemainder(dividingBy: 1.0) as Double
        let kilometers = afstand / 1000 - (afstand / 1000).truncatingRemainder(dividingBy: 0.1)
        if afstand < 1000.0 {
            return "\(meters) m"
        }
        else {
            return "\(kilometers) km"
        }

    }


    //voegt snel een afvalbakpin toe
    func addAfvalbak(pinLocatie: CLLocationCoordinate2D) -> MKAnnotation {
        return purePin(title: "Afvalbak", subtitle: afstandPuntTotUser(locatie1: pinLocatie), coordinate: pinLocatie) as MKAnnotation

    }

    //voegt sel een glasbakpin toe
    func addGlasbak(pinLocatie:CLLocationCoordinate2D) -> MKAnnotation {
        return purePin(title: "Glasbak", subtitle: afstandPuntTotUser(locatie1: pinLocatie), coordinate: pinLocatie)
    }

    //voegt snel een blikvangerpin toe
    func addBlikvanger(pinLocatie:CLLocationCoordinate2D) -> MKAnnotation {
        return purePin(title: "Blikvanger", subtitle: afstandPuntTotUser(locatie1: pinLocatie), coordinate: pinLocatie)
    }


    //voegt snel een volledige afvalbak pin + afstand toe
    func addFullAfvalbak(pinlocatie: CLLocationCoordinate2D) -> fullPin {
        return fullPin(title: "Afvalbak", subtitle: afstandPuntTotUser(locatie1: pinlocatie), coordinate: pinlocatie)
    }

    //voegt snel een volledige glasbak pin + afstand toe
    func addFullGlasbak(pinlocatie: CLLocationCoordinate2D) -> fullPin {
        return fullPin(title: "Glasbak", subtitle: afstandPuntTotUser(locatie1: pinlocatie), coordinate: pinlocatie)
    }

    //voegt snel een volledige blikvanger pin + afstand toe
    func addFullBlikvanger(pinlocatie: CLLocationCoordinate2D) -> fullPin {
        return fullPin(title: "Blikvanger", subtitle: afstandPuntTotUser(locatie1: pinlocatie), coordinate: pinlocatie)
    }







    //array met alle afvalbaklocaties
    let afvalbakLocaties: [CLLocationCoordinate2D] = [jacobbotkeweg1, jacobbotkeweg2, jacobbotkeweg3, jacobbotkeweg4, jacobbotkeweg5, jacobbotkeweg6, jacobbotkeweg7, aldlansdyk1, aldlansdyk2, aldlansdyk3, weideflora1, weideflora2, hempensweg1, hempensweg2, hempensweg3, hempensweg4, hempenserweg1, hempenserweg2, hempenserweg3, legedyk1, verlengdeschrans1, oostergoweg1, henridunantweg1, henridunantweg2, henridunantweg3, henridunantweg4, henridunantweg5, henridunantweg6, henridunantweg7, abbingapark1, abbingapark2, tijnjedyk1, tijnjedyk2, tijnjedyk3, tijnjedyk4, ipebrouwerssteeg1, nieuwestad1, nieuwestad2, nieuwestad3, nieuwestad4, nieuwestad5, nieuwestad6, nieuwestad7, nieuwestad8, nieuwestad9, nieuwestad10, nieuwestad11, nieuwestad12]

    //array met alle glasbaklocaties
    let glasbakLocaties: [CLLocationCoordinate2D] = [timothee1]

    //array met alle blikvangerlocaties
    let blikvangerLocaties: [CLLocationCoordinate2D] = [bitgummerdyk1]


    //slaat alle locaties op voor widget
    //UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(afvalbakLocaties, forKey: "afvalbakLocaties")
    //UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(glasbakLocaties, forKey: "glasbakLocaties")
    //UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(blikvangerLocaties, forKey: "blikvangerLocaties")



    //array met alle pinnen die worden toegevoegd
    var allePinnen: [MKAnnotation] = []

    //voegt alle afvalbakken toe aan allePinnen
    for item in afvalbakLocaties {
        allePinnen.append(addAfvalbak(pinLocatie: item))
    }

    //voegt alle glasbakken toe aan allePinnen
    for item in glasbakLocaties {
        allePinnen.append(addGlasbak(pinLocatie: item))
    }

    //voegt alle blikvangers toe aan allePinnen
    for item in blikvangerLocaties {
        allePinnen.append(addBlikvanger(pinLocatie: item))
    }


    //voegt alle pinnen toe aan de kaart
    mapView.addAnnotations(allePinnen)


    var fullPinnen:[fullPin] = []

    //voegt alle afvalbakken toe aan fullPinnen
    for item in afvalbakLocaties {
        fullPinnen.append(addFullAfvalbak(pinlocatie: item))
    }

    //voegt alle glasbakken toe aan fullPinnen
    for item in glasbakLocaties {
        fullPinnen.append(addFullGlasbak(pinlocatie: item))
    }

    //voegt alle blikvangers toe aan fullPinnen
    for item in blikvangerLocaties {
        fullPinnen.append(addFullBlikvanger(pinlocatie: item))
    }

    //sorteert de bakken in fullPinnen op afstand
    fullPinnen.sort {$0.afstand < $1.afstand}


    //slaat de 3 dichtsbijzijnde afvalbakken op
    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")!.set(fullPinnen[0].afstand, forKey: "closestpin1afstand")
    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(fullPinnen[0].title, forKey: "closestpin1naam")

    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")!.set(fullPinnen[1].afstand, forKey: "closestpin2afstand")
    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(fullPinnen[1].title, forKey: "closestpin2naam")

    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")!.set(fullPinnen[2].afstand, forKey: "closestpin3afstand")
    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(fullPinnen[2].title, forKey: "closestpin3naam")

    UserDefaults().synchronize()

Upvotes: 1

Views: 160

Answers (2)

Mandeep Singh
Mandeep Singh

Reputation: 2855

Create a new class in the same Project and add this code in your new class. Then check whether your didUpdateLocations method will called or not. And let me know whether this code will work for you or not.

@IBOutlet weak var mapView: MKMapView!

let manager = CLLocationManager()

   override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    manager.delegate = self
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.requestAlwaysAuthorization()
    manager.startUpdatingLocation()
    // Do any additional setup after loading the view, typically from a nib.
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let location: CLLocation = locations[0]
    let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
    //let span: MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
    //let region: MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)

    //store myLocation in UserDefauls


    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.latitude, forKey: "latitude")
    UserDefaults(suiteName: "group.Afvalbakfinder.Jordadema.userLocation")?.set(myLocation.longitude, forKey: "longitude")

    UserDefaults.standard.set(myLocation.latitude, forKey: "latitude")
    UserDefaults.standard.set(myLocation.longitude, forKey: "longitude")
    UserDefaults().synchronize()


    //region wel of niet? nog even over hebben
    //mapView.setRegion(region, animated: true)

    self.mapView.showsUserLocation = true
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print("Failed to find user's location: \(error.localizedDescription)")
}

Upvotes: 3

Mark Angelo Hernandez
Mark Angelo Hernandez

Reputation: 123

Check the following:

  1. Enable background modes and select location updates in you app targets's capabilities section.
  2. Add NSLocationUsageDescription in your app info plist file.
  3. Add Privacy - Location Always Usage Description in your info plist if you will use the location service while the app is in background or not running else add Privacy - Location When In Use Usage Description if you will only use the location service while the user uses your app.

Upvotes: 0

Related Questions