I am trying to get a user's latitude and longitude values, but the CLLocationManagerDelegate's methods are not getting called. Thanks in advance to anyone who can help me solve this.
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationmanager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationmanager.delegate = self;
locationmanager.desiredAccuracy = kCLLocationAccuracyBest
locationmanager.requestAlwaysAuthorization()
locationmanager.startUpdatingLocation()
}
//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)")
}
}
You can typically okay. To access user's current location you need physical device.
Still, there are second way to simulate location on simulator using Simulate Location option available above console in toolbar. This option available when your application is running.
Click on it to see list of location and select location to get device location on simulator. It's will be not current location but Simulate Location will set simulator location to your selected location. See following image:
You can also add your custom GPX file to load your current location. You can also add your Customer Location from debug menu of simulator. See following image:
I hope this will help you.
import following framework
Import CoreLocation
if you want Display map
Import MapKit
You can determine user’s current location by declaring
CLLocationManager instance:
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
Make sure you set following privacy permission.
Also, make sure simulator’s location service is ON.
Privacy - Location Always and When In Use Usage Description
Privacy - Location When In Use Usage Description
Related
I am using CoreLocation in IOS Swift to get the current coordinates but for some cases, it gives me closest to my desired location while sometimes the coordinates are many meters away from my given address. please check my code which I am using is there any other way to get an accurate current location coordinates.?
My Code is :
import CoreLocation
var locationManager:CLLocationManager!
var userLat = 0.0
var userLong = 0.0
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager = CLLocationManager()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled(){
self.locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations:
[CLLocation]) {
guard let userLocation :CLLocation = locations.first else{return}
userLat = userLocation.coordinate.latitude
userLong = userLocation.coordinate.longitude
//current location
print("current location latitude is :%#", userLat)
print("current location longitude is :%#", userLong)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(Error: \(error)")
}
Please help me some time current location is accurate and sometimes it's too meters away. Thanks
Assuming the user of your app has allowed you use precise locations you still need to take into account the fact that the location provided is only as accurate as the hardware can provide. It takes time for the location to get accurate and you may see several calls to didUpdateLocations as the system warms up.
You can use horizontalAccuracy and verticalAccuracy on a CLLocation to make decisions on what to do with a position update.
On my main CollectionView (the app home page), I would like to update the locations (i.e. the cells themselves) based on the closest location to the user. I am storing my locations in Firebase and will be using GeoFire and core location in order to properly list out the locations in distance order from the user.
Other posts have said that the best practice for observers involves loading it in viewWillAppear; however, I have been unable to obtain the user's location before this runs and do not have a centered point for my GeoFire query. Most examples related to CoreLocation involve maps or preselected coordinates, but I wasn't planning on using a map within this controller and want to dynamically load based off of user location.
I have researched loading didUpdateLocations within AppDelegate, but have not been able to call that method there either. What is the best way to get user location coordinates before running a GeoFire query when loading that returned data in viewWillAppear or do you need to set a region and check if a user has entered within that region?
var locationDict = [CLLocation]() //using this variable to pass values outside the function to the query
override func viewWillAppear(animated: Bool) {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let recentLocation = locations[0]
locationDict.append(recentLocation)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
There is quite a lot missing in your code, but in short (what works for me):
.requestLocation in viewWillAppear
.startUpdatingLocation() in viewDidAppear. (so twice).
var justStartedUsingMap = true
In didUpdateLocations:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
guard let myLocation:CLLocation = manager.location else {return}
let location:CLLocationCoordinate2D = myLocation.coordinate
let region = MKCoordinateRegion(center: location, span: MKCoordinateSpan(latitudeDelta: 0.12, longitudeDelta: 0.12))
if justStartedUsingMap == true {
self.currentLocationSearch(myLocation)
justStartedUsingMap = false
} else {
locationManager.stopUpdatingLocation()
}
self.map.setRegion(region, animated: true)
}
func currentLocationSearch(_ location: CLLocation) {
// the geofire observer
}
info.plist file:
<key>NSLocationWhenInUseUsageDescription</key>
<string>This project would like to know your location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>location when app is in background</string>
As shown above, have added the key/value pairs for the info.plist
The problem i'm facing is that the first time i ran the app it prompted me for authorization, but, on subsequent runs the popup hasn't appeared.
second, I'm trying to print the locations from
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) using the print(location) but nothing is printed.
in the debug options i have set location as "city bicycle ride"
The code i'm using is as follows.
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate , CLLocationManagerDelegate {
#IBOutlet var map: MKMapView!
//use the locManager to get the users location
var locManager = CLLocationManager()
override func viewDidLoad() {
locManager.delegate = self
locManager.desiredAccuracy = kCLLocationAccuracyBest
locManager.requestWhenInUseAuthorization()
super.viewDidLoad()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
iOS will ask only once for location authorization. If the user denies, he will have to change this in the device settings manually. If he agrees, you will be able to obtain the location until he blocks it in the device settings.
So this code:
locManager.requestWhenInUseAuthorization()
will prompt a popup only 1 time. The problem is that you probably forget to call:
locManager.startUpdatingLocation()
You need to call this every time you want to start obtaining the location.
use this
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestLocation()
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
I've tried looking at other solutions such as: requestWhenInUseAuthorization() not Work in iOS 8 With NSLocationWhenInUseUsageDescription Key in Info.plist
But I can't get authorization prompt to get location.
That person's issue in that other question was that he had is manager inside his viewDidLoad, I do not, but still an authorization prompt is not showing up. I've updated my plist:
and have my manager outside of my viewDidLoad:
import UIKit
import AVFoundation
import MapKit
class SecondViewController: UIViewController, CLLocationManagerDelegate {
let locationManager: CLLocationManager = CLLocationManager()
var player = AVPlayer()
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
println("Got to end of locationmanager")
//playentryaudio() // User plugged in mic -- start playing entry audio.
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
println("Got to locationmngsr")
var userlocation = locations[0] as! CLLocation
var latitude: CLLocationDegrees = userlocation.coordinate.latitude
var longitude: CLLocationDegrees = userlocation.coordinate.longitude
println(latitude)
println(longitude)
} //snip rest of code
Since It's not getting auth, It's never hitting the locationManager function.
The prompt only shows if CLLocationManager.authorizationStatus() == .NotDetermined. If the user previously denied access, you won't see the prompt anymore. You should check the status before self.locationManager.requestWhenInUseAuthorization(). If it shows anything but .NotDetermined, look at the location settings for the app and the device.
If the status is .NotDetermined and the prompt still does not show, I would double check spelling of the NSLocationWhenInUseUsageDescription.
I want to find the latitude and longitude of location in ios8 and display it in the label. I have added the "NSLocationWhenInUseUsageDescription" property in info.plist. I have turned on the location settings for this particular app.But even then it is not updating the label.No logs are working too. My code is as follows:-
#IBAction func clicked(sender: UIButton) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
let locat = locations[0] as! CLLocation
latitude.text = String(stringInterpolationSegment: locat.coordinate.latitude)
longitude.text = String(stringInterpolationSegment: locat.coordinate.longitude)
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
Your locations:[AnyObject]! actually is an [CLLocation] just get its last object and use CLLocation's coordinate property.
Complete Solution
add CoreLocation.framework to BuildPhases -> Link Binary With Libraries
import CoreLocation to your class - probably ViewController.swift
add CLLocationManagerDelegate to your class decleration
Add NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription to plist
init location manager:
locationManager = CLLocationManager()
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
get User Location By:
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var userLocation:CLLocation = locations[0] as! CLLocation
let long = userLocation.coordinate.longitude;
let lat = userLocation.coordinate.latitude;
//Do What ever you want with it
}
i.e Add in your plist file.,
NSLocationWhenInUseUsageDescription = Request permission to use location service when the apps is in background.
if you Are using Simulator then see you have to create one Location.GPX File To get Lat Long of Location.
Create new file Named As "Location.GPX"
-> Add your Static Lat Long for testing Purpose.
as given Below
<?xml version="1.0"?>
<gpx version="1.1" creator="Xcode">
<wpt lat="23.0271480" lon="72.5085160">
<name>Ahmedabad</name>
</wpt>
</gpx>
then
-> Go to Xcode -> Edit Scheme -> Select Location.GPX File and Rubn project Again..
One more thing to keep in mind along with solution given by Mehul is not toloose reference to your CLLocationManger() object.
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
It is asynchronus and if you loose reference to your lCLLocationManger() object then it won't get called and you will not get the location even after doing after everything right.