Get User's Current Location / Coordinates

2019-01-02 14:21发布

问题:

How can I store the user's current location and also show the location on a map?

I am able to show pre-defined coordinates on a map, I just don't know how to receive information from the device.

Also I know I have to add some items into a Plist. How can I do that?

回答1:

To get a user's current location you need to declare:

let locationManager = CLLocationManager()

In viewDidLoad() you have to instantiate the CLLocationManager class, like so:

// Ask for Authorisation from the User.
self.locationManager.requestAlwaysAuthorization() 

// For use in foreground
self.locationManager.requestWhenInUseAuthorization()

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

Then in CLLocationManagerDelegate method you can get user's current location coordinates:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
    print("locations = \(locValue.latitude) \(locValue.longitude)")
}

In the info.plist you will have to add NSLocationAlwaysUsageDescription and your custom alert message like; AppName(Demo App) would like to use your current location.



回答2:

you should do those steps:

  1. add CoreLocation.framework to BuildPhases -> Link Binary With Libraries (no longer necessary as of XCode 7.2.1)
  2. import CoreLocation to your class - most likely ViewController.swift
  3. add CLLocationManagerDelegate to your class declaration
  4. add NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription to plist
  5. init location manager:

    locationManager = CLLocationManager()
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
    locationManager.startUpdatingLocation()
    
  6. get User Location By:

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


回答3:

Here is how I am

getting current location and showing on Map in Swift 2.0

Make sure you have added CoreLocation and MapKit framework to your project (This doesn't required with XCode 7.2.1)

import Foundation
import CoreLocation
import MapKit

class DiscoverViewController : UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var map: MKMapView!
    var locationManager: CLLocationManager!

    override func viewDidLoad()
    {
        super.viewDidLoad()

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

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

        let location = locations.last! as CLLocation

        let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))

        self.map.setRegion(region, animated: true)
    }
}

Here is the result screen



回答4:

NSLocationWhenInUseUsageDescription = Request permission to use location service when the apps is in background. in your plist file.

If this works then please vote the answer.



回答5:

First import Corelocation and MapKit library:

import MapKit
import CoreLocation

inherit from CLLocationManagerDelegate to our class

class ViewController: UIViewController, CLLocationManagerDelegate

create a locationManager variable, this will be your location data

var locationManager = CLLocationManager()

create a function to get the location info, be specific this exact syntax works:

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

in your function create a constant for users current location

let userLocation:CLLocation = locations[0] as CLLocation // note that locations is same as the one in the function declaration  

stop updating location, this prevents your device from constantly changing the Window to center your location while moving (you can omit this if you want it to function otherwise)

manager.stopUpdatingLocation()

get users coordinate from userLocatin you just defined:

let coordinations = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude,longitude: userLocation.coordinate.longitude)

define how zoomed you want your map be:

let span = MKCoordinateSpanMake(0.2,0.2) combine this two to get region:

let region = MKCoordinateRegion(center: coordinations, span: span)//this basically tells your map where to look and where from what distance

now set the region and choose if you want it to go there with animation or not

mapView.setRegion(region, animated: true)

close your function }

from your button or another way you want to set the locationManagerDeleget to self

now allow the location to be shown

designate accuracy

locationManager.desiredAccuracy = kCLLocationAccuracyBest

authorize:

 locationManager.requestWhenInUseAuthorization()

to be able to authorize location service you need to add this two lines to your plist

get location:

locationManager.startUpdatingLocation()

show it to the user:

mapView.showsUserLocation = true

This is my complete code:

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var mapView: MKMapView!

    var locationManager = CLLocationManager()


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

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func locateMe(sender: UIBarButtonItem) {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()

        mapView.showsUserLocation = true

    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let userLocation:CLLocation = locations[0] as CLLocation

        manager.stopUpdatingLocation()

        let coordinations = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude,longitude: userLocation.coordinate.longitude)
        let span = MKCoordinateSpanMake(0.2,0.2)
        let region = MKCoordinateRegion(center: coordinations, span: span)

        mapView.setRegion(region, animated: true)

    }
}


回答6:

Swift 3.0

If you don't want to show user location in map, but just want to store it in firebase or some where else then follow this steps,

import MapKit
import CoreLocation

Now use CLLocationManagerDelegate on your VC and you must override the last three methods shown below. You can see how the requestLocation() method will get you the current user location using these methods.

class MyVc: UIViewController, CLLocationManagerDelegate {

  let locationManager = CLLocationManager()

 override func viewDidLoad() {
    super.viewDidLoad()

    isAuthorizedtoGetUserLocation()

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

 //if we have no permission to access user location, then ask user for permission.
func isAuthorizedtoGetUserLocation() {

    if CLLocationManager.authorizationStatus() != .authorizedWhenInUse     {
        locationManager.requestWhenInUseAuthorization()
    }
}


//this method will be called each time when a user change his location access preference.
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    if status == .authorizedWhenInUse {
        print("User allowed us to access location")
        //do whatever init activities here.
    }
}


 //this method is called by the framework on         locationManager.requestLocation();
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    print("Did location updates is called")
    //store the user location here to firebase or somewhere 
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print("Did location updates is called but failed getting location \(error)")
}

}

Now you can code the below call once user sign in to your app. When requestLocation() is invoked it will further invoke didUpdateLocations above and you can store the location to Firebase or anywhere else.

if CLLocationManager.locationServicesEnabled() {
            locationManager.requestLocation();
 }

if you are using GeoFire then in the didUpdateLocations method above you can store the location as below

geoFire?.setLocation(locations.first, forKey: uid) where uid is the user id who logged in to the app. I think you will know how to get UID based on your app sign in implementation. 

Last but not least, go to your Info.plist and enable "Privacy -Location when in Use Usage Description."

When you use simulator to test it always give you one custom location that you configured in Simulator -> Debug -> Location.



回答7:

Import library like:

import CoreLocation

set Delegate:

CLLocationManagerDelegate

Take variable like:

var locationManager:CLLocationManager!

On viewDidLoad() write this pretty code:

 locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()

    if CLLocationManager.locationServicesEnabled(){
        locationManager.startUpdatingLocation()
    }

Write CLLocation delegate methods:

    //MARK: - location delegate methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let userLocation :CLLocation = locations[0] as CLLocation

    print("user latitude = \(userLocation.coordinate.latitude)")
    print("user longitude = \(userLocation.coordinate.longitude)")

    self.labelLat.text = "\(userLocation.coordinate.latitude)"
    self.labelLongi.text = "\(userLocation.coordinate.longitude)"

    let geocoder = CLGeocoder()
    geocoder.reverseGeocodeLocation(userLocation) { (placemarks, error) in
        if (error != nil){
            print("error in reverseGeocode")
        }
        let placemark = placemarks! as [CLPlacemark]
        if placemark.count>0{
            let placemark = placemarks![0]
            print(placemark.locality!)
            print(placemark.administrativeArea!)
            print(placemark.country!)

            self.labelAdd.text = "\(placemark.locality!), \(placemark.administrativeArea!), \(placemark.country!)"
        }
    }

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

Now set permission for access the location, so add these key value into your info.plist file

 <key>NSLocationAlwaysUsageDescription</key>
<string>Will you allow this app to always know your location?</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Do you allow this app to know your current location?</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Do you allow this app to know your current location?</string>

100% working without any issue. TESTED



回答8:

first add two frameworks in your project

1: MapKit

2: Corelocation (no longer necessary as of XCode 7.2.1)

Define in your class

var manager:CLLocationManager!
var myLocations: [CLLocation] = []

then in viewDidLoad method code this

manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()

//Setup our Map View
mapobj.showsUserLocation = true

do not forget to add these two value in plist file

1: NSLocationWhenInUseUsageDescription

2: NSLocationAlwaysUsageDescription


回答9:

 override func viewDidLoad() {

    super.viewDidLoad()       
    locationManager.requestWhenInUseAuthorization();     
    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
        locationManager.startUpdatingLocation()
    }
    else{
        print("Location service disabled");
    }
  }

This is your view did load method and in the ViewController Class also include the mapStart updating method as follows

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
    var locValue : CLLocationCoordinate2D = manager.location.coordinate;
    let span2 = MKCoordinateSpanMake(1, 1)    
    let long = locValue.longitude;
    let lat = locValue.latitude;
    print(long);
    print(lat);        
    let loadlocation = CLLocationCoordinate2D(
                    latitude: lat, longitude: long            

   )     

    mapView.centerCoordinate = loadlocation;
    locationManager.stopUpdatingLocation();
}

Also do not forget to add CoreLocation.FrameWork and MapKit.Framework in your project (no longer necessary as of XCode 7.2.1)



回答10:

import CoreLocation
import UIKit

class ViewController: UIViewController, CLLocationManagerDelegate {

    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
    } 

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status != .authorizedWhenInUse {return}
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.startUpdatingLocation()
        let locValue: CLLocationCoordinate2D = manager.location!.coordinate
        print("locations = \(locValue.latitude) \(locValue.longitude)")
    }
}

Because the call to requestWhenInUseAuthorization is asynchronous, the app calls the locationManager function after the user has granted permission or rejected it. Therefore it is proper to place your location getting code inside that function given the user granted permission. This is the best tutorial on this I have found on it.



回答11:

// its with strongboard 
@IBOutlet weak var mapView: MKMapView!

//12.9767415,77.6903967 - exact location latitude n longitude location 
let cooridinate = CLLocationCoordinate2D(latitude: 12.9767415 , longitude: 77.6903967)
let  spanDegree = MKCoordinateSpan(latitudeDelta: 0.2,longitudeDelta: 0.2)
let region = MKCoordinateRegion(center: cooridinate , span: spanDegree)
mapView.setRegion(region, animated: true)


标签: