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.
Related
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
I have the following code:
import CoreLocation
class ViewController: UIViewController, NetworkingDelegate, CLLocationManagerDelegate {
let locationManager: CLLocationManager = CLLocationManager()
and then later:
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
and then I implement the delegate methods lower in the VC
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
for currentLocation in locations{
print("\(index)\(currentLocation)")
}
print("Did Location Delegate get called?")
let location: CLLocation = locations.first as! CLLocation
print(location)
self.lat = String(format: "%f", location.coordinate.latitude)
self.long = String(format: "%f", location.coordinate.longitude)
}
In build phases, "Link Binary With Libraries" has CoreLocation.framework selected.
The proper privacy in plist is present: Privacy - Location Usage Description as is Privacy - Location When In Use Usage Description.
The location is still not being gotten. I am using simulator in Xcode 9.4.1 targeting iOS 11. What am I missing here?
The problem is that func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) is years out of date. Update your code for modern Swift. Here's how the declaration should look:
https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate/1423615-locationmanager
Here is my VC code:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
mapView.showsUserLocation = true
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
mapView.showsUserLocation = (status == .AuthorizedAlways)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
print("locations = \(locValue.latitude) \(locValue.longitude)")
}
}
I have also added NSLocationWhenInUseUsageDescription in my plist file. And I have the CoreLocation and MapKit frameworks, any idea why this is not working? It doesn't show the user location on the map nor does it print out the user's coordinates. Haven't found anything online on on stack overflow.
This works for me
Swift 2 - (Xcode 7.2.1)
ViewController.swift
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.locationManager.stopUpdatingLocation()
let latestLocation = locations.last
let latitude = String(format: "%.4f", latestLocation!.coordinate.latitude)
let longitude = String(format: "%.4f", latestLocation!.coordinate.longitude)
print("Latitude: \(latitude)")
print("Longitude: \(longitude)")
}
}
info.plist
Add a new line
Information Property List: NSLocationWhenInUseUsageDescription
Type: String
Value: The application uses this information to show you your location
Try getting the location by getting the last object for the array locations in the method locationManager(_:,didUpdateLocations locations: [CLLocations]) .
Something like this:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = locations.last!
print("locations = \(locValue.latitude) \(locValue.longitude)")
}
you have to use these location access permission in your plist.
NSLocationAlwaysAndWhenInUseUsageDescription
NSLocationWhenInUseUsageDescription
you are not using always and in InUse permiossion
Note by Apple:
This app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain both NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription keys with string values explaining to the user how the app uses this data
I am trying to use CoreLocation (once permission is granted) to get a user's CLLocationCoordinate2D, so that I can pass that information to an Uber deeplink (after a UIButton within my TableView is pressed).
I've figured out how to get the coordinates as CLLocations, and turn them into CLLocationCoordinates2D in the didUpdateLocations method, but can't seem to transfer them over to my buttonPressed function.
Can anyone explain how I can properly transfer the coordinates info to the uberButtonPressed method? I am also confused about how to get the locationManager to stop updating location once a suitable location is determined. Any help is much appreciated. By the way I am using this to instantiate Uber: https://github.com/kirby/uber
import UIKit
import CoreLocation
import MapKit
class ATableViewController: UITableViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
var location: CLLocation?
var coordinate: CLLocationCoordinate2D?
// Implemented tableView methods etc here...
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
let newLocation = locations.last as! CLLocation
println("DID UPDATE LOCATIONS \(newLocation)")
location = newLocation
coordinate = location!.coordinate
println("WE HAVE THE COORDINATES \(coordinate!.latitude) and \(coordinate!.longitude)") // this prints along with DID UPDATE LOCATIONS
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("error:" + error.localizedDescription)
}
func uberButtonPressed(sender: UIButton!) {
let senderButton = sender
println(senderButton.tag)
let authStatus: CLAuthorizationStatus = CLLocationManager.authorizationStatus()
if authStatus == .NotDetermined {
locationManager.requestWhenInUseAuthorization()
return
}
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
var pickupLocation = coordinate! // fatal error: unexpectedly found nil while unwrapping an Optional value
println(pickupLocation)
// // Create an Uber instance
// var uber = Uber(pickupLocation: pickupLocation)
//
// Set a few optional properties
// uber.pickupNickname = "OK"
//
// uber.dropoffLocation = CLLocationCoordinate2D(latitude: 47.591351, longitude: -122.332271)
// uber.dropoffNickname = "whatever"
//
// // Let's do it!
// uber.deepLink()
//
}
You should move var pickupLocation = coordinate! into your didUpdateLocations. Once assigned, you can call locationManager.stopUpdatingLocation() also from inside 'didUpdateLocation or your value for coordinate with keep updating. After stopping the locationManager, call a NEW function to run the rest of your code currently in func uberButtonPressed
I had the same problem.
Instead of calling the delegate method like this:
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
debugPrint("NOT CALLED-- didUpdateLocations AnyObject")
}
I changed into:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
debugPrint("CALLED-- didUpdateLocations CLLocation")
}
The problem is that you are unwrapping coordinate which is a CLLocationCoordinate2D? with a !. Since coordinate is from location which is a CLLocation?. It is possible that coordinate is nil and location is nil, especially before location services have had a chance to kick in. Only run the rest of uberButtonPressed: for the case where coordinate and location are not nil by using if let currentCoordinate = coordinate?, and in that case, call locationManager.stopUpdatingLocation().
I've been trying to get this to work for awhile now, and I've come here to ask- how do I go about with using the CLLocationManagerDelegate methods in Swift? I've put this at the top of my class:
var locationManager = CLLocationManager()
I've put the following into my viewDidLoad method:
locationManager.delegate = self
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
And I've tried using these delegate methods with no avail:
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) {
locationReceived = true
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
locationReceived = false
}
I've also tried using #optional in front of the functions, but Xcode then throws a compiler error. Any ideas?
You need to add the NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key to your plist if you haven't already, they are now mandatory,
iOS8+ requires one of these two strings to be set to use locations. Which one you use depends on how you intend ask for the location.
Use NSLocationAlwaysUsageDescription for apps that want to use the device's location even when the app is not open and being used.
Use NSLocationWhenInUseUsageDescription for apps that want to use the device's location only when the app is open and in use.
Note: When you add the strings, before you build and run, delete the app off your device and let it do a fresh install. It seems that if the app was authorized to use locations before you upgraded to iOS8 it doesn’t ask for your permission again and doesn’t see that you set those strings. Doing a delete and clean install solves this.
Setting either of the strings prompts a pop up on install/first use along the lines of: "Allow "ThisApp" to access your location even when you are not using the App"
Here's a Screenshot of the plist file.
First add this two line in plist file
1) NSLocationWhenInUseUsageDescription
2) NSLocationAlwaysUsageDescription
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate
var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
}
func initLocationManager() {
seenError = false
locationFixAchieved = false
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.locationServicesEnabled
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
locationManager.stopUpdatingLocation()
if (error) {
if (seenError == false) {
seenError = true
print(error)
}
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) {
if (locationFixAchieved == false) {
locationFixAchieved = true
var locationArray = locations as NSArray
var locationObj = locationArray.lastObject as CLLocation
var coord = locationObj.coordinate
println(coord.latitude)
println(coord.longitude)
}
}
func locationManager(manager: CLLocationManager!,
didChangeAuthorizationStatus status: CLAuthorizationStatus) {
var shouldIAllow = false
switch status {
case CLAuthorizationStatus.Restricted:
locationStatus = "Restricted Access to location"
case CLAuthorizationStatus.Denied:
locationStatus = "User denied access to location"
case CLAuthorizationStatus.NotDetermined:
locationStatus = "Status not determined"
default:
locationStatus = "Allowed to location Access"
shouldIAllow = true
}
NSNotificationCenter.defaultCenter().postNotificationName("LabelHasbeenUpdated", object: nil)
if (shouldIAllow == true) {
NSLog("Location to Allowed")
// Start location services
locationManager.startUpdatingLocation()
} else {
NSLog("Denied access: \(locationStatus)")
}
}
To get User Current Location :-
Step 1: let locationManager = CLLocationManager() // make object of CLLocationManager class.
Step 2: In viewDidLoad instantiate the CLLocationManager class like,
// For use in background
self.locationManager.requestAlwaysAuthorization()
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if (CLLocationManager.locationServicesEnabled())
{
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
Step 3: Now implement the delegate methods of CLLocationManager
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var locValue:CLLocationCoordinate2D = manager.location.coordinate
println("locations = \(locValue.latitude) \(locValue.longitude)")
}
Step 4:
Don't forget to add NSLocationAlwaysUsageDescription in the Info.plist as in iOS 8 it is mandatory to add this. This will ask permission to use user's location.
I had the same issue. didUpdateLocations - was not working. Run your app.
Go to the Settings page -> Privacy -> Location and turn off Location Services. didFailWithError will catch the error about absent Location Services. Then turn it on. Since that moment didUpdateLocations will catch locations.
This is a bit of an old thread, yet none of the above worked for me on Swift 2.2 xCode 7.3.1.
The problem is I was using:
func locationManager(manager: CLLocationManager!, didUpdateLocation locations: [AnyObject]!) {
print("Got location")
locationManager.stopUpdatingLocation()
}
And this never got called. When I changed to:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Got location")
locationManager.stopUpdatingLocation()
}
It all worked out. Seems like the delegate is not called when using [AnyObject]