简体   繁体   中英

didUpdateLocations not working in Swift 3

I am updating my app to Swift 3 and cannot get it to print out location coordinates.

I have Privacy - Location When In Use, Privacy - Location Always, and Privacy - Location Usage Descriptions in my info.plist file.

@IBAction func activateTestModeButton(_ sender: AnyObject) {

    locationManager.startUpdatingLocation()
    print("Method called")
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations newLocation: CLLocation, fromLocation oldLocation: CLLocation){
        loadUser()
        loadCoreData()

        print("Updating location")

        let latitude:String = "\(newLocation.coordinate.latitude)"
        let longitude:String = "\(newLocation.coordinate.longitude)"

        print("Latitude = \(newLocation.coordinate.latitude)")
        print("Longitude = \(newLocation.coordinate.longitude)")      }

It prints "Method Called" but nothing else. I also have the didFailWithError method included which I believe is required and it is not printing anything:

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error){
    print("Location manager failed with error = \(error)")
}

Other pertinent code which one would assume I'd have:

/* Asking the user if we can access their location */
func Authorization(){
    if CLLocationManager.locationServicesEnabled()
    {
        switch CLLocationManager.authorizationStatus()
        {
        case .authorizedAlways:
            print("Authorized")
        case .authorizedWhenInUse:
            print("Authorized when in use")
        case .denied:
            displayAlertWithTitle("Not determined", message: "Location services are not allowed for this app")
        case .notDetermined:
            print("Not Determined")
            if let manager = self.locationManager
            {
                manager.requestWhenInUseAuthorization()
            }
        case .restricted:
            displayAlertWithTitle("Restricted", message: "Location services are not allowed for this app")
        }
    }
    else
    {
        print("Location services are not enabled")
    }
}

/* Location Detection */
func permission(){
    if CLLocationManager.authorizationStatus() == .notDetermined
    {
        locationManager?.requestAlwaysAuthorization()
    }
}

override func viewDidAppear(_ animated: Bool){
    super.viewDidAppear(animated)
    Authorization()
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.locationManager = CLLocationManager()
    self.locationManager?.desiredAccuracy = kCLLocationAccuracyBest
    self.locationManager?.distanceFilter = 200
    self.locationManager?.delegate = self

}

I would reccomend you to move the code that manages the Location to a class like this one. This code is from an app i made a few months ago, i tested it to see if it works and i does. So give it a try. You just need to create an object of this class. I left a commented print in the method locationManager(:didupdate) , you can uncomment it to see all the changes in you location.

I know it is not perfect but it got me the job done.

import Foundation
import MapKit
import CoreLocation

class Location: CLLocationManager, CLLocationManagerDelegate  {
    private var latitude:Double
    private var longitud:Double
    private let locationManager = CLLocationManager()

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    override init() {
        self.latitude = 0.0
        self.longitud = 0.0
        self.locationManager.requestWhenInUseAuthorization()

        super.init()

        if CLLocationManager.locationServicesEnabled() {
            self.locationManager.delegate = self
            self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            self.locationManager.requestAlwaysAuthorization()
            self.locationManager.startUpdatingLocation()
        }
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    internal func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let locValue:CLLocationCoordinate2D = (manager.location?.coordinate)!
        //print("locations = \(locValue.latitude) \(locValue.longitude)")

        self.latitude = locValue.latitude
        self.longitud = locValue.longitude
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    func getLatitude()->NSNumber{
        return self.latitude as NSNumber
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    func getLongitude()->NSNumber{
        return self.longitud as NSNumber
    }

}

You need to be absolutely certain that the CLLocationManager instance, on which you're calling startUpdatingLocation() is not nil .

Also strange is that the code you've shared in viewDidLoad initializes the locationManager as an Optional property, however when you call startUpdatingLocation() its no longer an Optional? If that's right is that IBAction hooked up in some other ViewController? Or you haven't shared all the code in that IBOutlet that explicitly unwraps the Optional ? Or maybe that is a typo?

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