I have written a basic program that uses the devices location. I have written it and this is the basics of the ViewController
override func viewDidLoad() {
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Location Updated")
lat = String(format: "%f", locationManager.location!.coordinate.latitude)
long = String(format: "%f", locationManager.location!.coordinate.longitude)
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Failed Loc: \(error)")
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
print("Auth Changed: \(status)")
}
In my info.plist I have this, as required:
<key>NSLocationWhenInUseUsageDescription</key>
<string>uses loc</string>
I ran the code on the simulator and it gives me
Failed Loc: Error Domain=kCLErrorDomain Code=0 "(null)"
I then sepcified the location of the simulator and it prints
Location Updated
as it should. Oddly; however, when i upload this onto my ios device it asks for permission and then I get no output. There are no errors that output, it doesn't even trigger didChangeAuthorizationStatus
**Edit: here is the header of the ViewController file:
import CoreLocation
class Central_ViewController: UIViewController, UIScrollViewDelegate, UITabBarDelegate, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
**Edit 2:
self.locationManager.requestWhenInUseAuthorization()
if(CLLocationManager.locationServicesEnabled()) {
print("Location Services Enabled")
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.startUpdatingLocation()
}else {
print("Location Services NOT Enabled") // This needs to be completed to produce an error
}
Prints
Location Services Enabled
Location Services Enabled
Yet it still does not update location nor produce an error.
First you should check if NSLocationWhenInUseUsageDescription is in the appropriate Info.plist, the one for the app. This is because there are many Info.plists in a project, even the GoogleMaps framework has one.
You will notice the app will prompt you to allow obtaining locations once the proper Info.plist has the NSLocationWhenInUseUsageDescription.
Then don't use locationServicesEnabled to check if location services is allowed to be used. Use the following instead, this checks the authorization:
if CLLocationManager.authorizationStatus == .NotDetermined {
self.locationManager.requestWhenInUseAuthorization()
}
self.locationManager.startUpdatingLocation()
Related
I need to get the geographical coordinates on Mac OS. Here is my code, but an error is reported when running: domain = kclerrordomain code = 0 "(null)"
import Cocoa
import CoreLocation
let locationManager:CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//设置定位服务管理器代理
locationManager.delegate = self
//设置定位进度
locationManager.desiredAccuracy = kCLLocationAccuracyBest //最佳定位
//更新距离
// locationManager.distanceFilter = 100
//发出授权请求
locationManager.requestAlwaysAuthorization()
if (CLLocationManager.locationServicesEnabled()){
//允许使用定位服务的话,开始定位服务更新
// print("定位开始")
}
}
extension ViewController:CLLocationManagerDelegate{
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//获取最新的坐标
let currLocation : CLLocation = locations.last! // 持续更新
print("纬度:\(currLocation.coordinate.latitude) 纬度:\(currLocation.coordinate.longitude) 海拔:\(currLocation.altitude) 水平精度:\(currLocation.horizontalAccuracy) 垂直精度:\(currLocation.verticalAccuracy) 方向:\(currLocation.course) 速度:\(currLocation.speed)")
}
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
print("location manager auth status changed to:" )
switch status {
case .restricted:
print("status restricted")
case .denied:
print("status denied")
case .authorized:
print("已授权")
locationManager.startUpdatingLocation()
case .notDetermined:
print("status not yet determined")
default:
print("unknown state: \(status)")
}
}
func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
print( "location manager failed with error \(error)" )
}
}
enter image description here
When running application:
enter image description here
You need to add location usage description in your info.plist file. After adding your info.plist should look like this .
Add this line in viewDidLoad.
manager.startUpdatingLocation()
Then add the delegate method that updates the location.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations.last?.coordinate)
}
I am using Google maps SDK with swift 3.I want to get the current location on a map but I am not able to get current location in the real device but in the simulator, it shows the location of apple.But on the real device, it shows the current location of set in the app scheme otherwise it shows the error "Error: Error Domain=kCLErrorDomain Code=0 "(null)"". I am using below code to get the current location.Please help me.This code works in ios 10 but not work in ios 9
#IBOutlet weak var view_map: GMSMapView!
let locationManager = CLLocationManager()
var didFindMyLocation = false
override func viewDidLoad() {
super.viewDidLoad()
view_map.isMyLocationEnabled = true
// //Location Manager code to fetch current location
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
if #available(iOS 9.0, *) {
locationManager.allowsBackgroundLocationUpdates = true
locationManager.requestLocation()
}
locationManager.startUpdatingLocation()
}
//Location Manager delegates
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!, zoom: 17.0)
self.view_map.animate(to: camera)
//Finally stop updating location otherwise it will come again and again in this delegate
self.locationManager.stopUpdatingLocation()
}
// Handle authorization for the location manager.
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted:
print("Location access was restricted.")
case .denied:
print("User denied access to location.")
// Display the map using the default location.
view_map.isHidden = false
case .notDetermined:
print("Location status not determined.")
case .authorizedAlways: fallthrough
case .authorizedWhenInUse:
print("Location status is OK.")
}
}
// Handle location manager errors.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.stopUpdatingLocation()
print("Error: \(error)")
}
//Add these in your info.plist
<key>NSLocationAlwaysUsageDescription</key>
<string>Reason to access location background usage description</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Reason to access location usage description</string>
I'm working on an app that requires getting the user's current coordinates. I was planning on doing this through CLLocationManager's didUpdateLocations method. For some reason, didUpdateLocations is not being executed. However, it appears that locationManager.startUpdatingLocation() is being called successfully. None of the other possible solutions I've seen on this site have worked for me. I already added NSLocationAlwaysUsage to info.plist. Here is the entirety of my code:
import UIKit
import MapKit
import CoreLocation
var region: MKCoordinateRegion!
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var map: MKMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse, .authorizedAlways:
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
print("Updating location now")
}
case .notDetermined:
locationManager.requestAlwaysAuthorization()
case .restricted, .denied:
print("User must enable access in settings")
break
}
if (region == nil){
}
else {
map.setRegion(region!, animated: true)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Got location")
let userLocation:CLLocation = locations[0]
let lat:CLLocationDegrees = userLocation.coordinate.latitude
let long:CLLocationDegrees = userLocation.coordinate.longitude
let currentPos:CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat, long)
didUpdateRegion(position: currentPos)
print(lat)
print(long)
}
func didUpdateRegion(position: CLLocationCoordinate2D) {
let span = MKCoordinateSpanMake(0.075, 0.075)
region = MKCoordinateRegion(center: position, span: span)
}
func locationManager(_manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
// If status has not yet been determied, ask for authorization
manager.requestWhenInUseAuthorization()
break
case .authorizedWhenInUse:
// If authorized when in use
manager.startUpdatingLocation()
break
case .authorizedAlways:
// If always authorized
manager.startUpdatingLocation()
break
case .restricted:
print("User must activate location services in settings")
break
case .denied:
print("User must activate location services in settings")
break
default:
break
}
}
When I run this code on both the simulator and an actual device, I get the notification to allow location tracking. After accepting that, the console displays "Updating location now," but never gets to printing "Got location." Thank you for any light you can shed on this issue, I'm new to app development in general.
EDIT: I added in the entirety of my code instead of just the parts I thought were relevant. Basically, I'm trying to get the region shown on the map to follow the user. I attempt to do this by updating the variable "region" every time the didUpdateLocations function fires.
Am I getting it right and you only added one key - NSLocationAlwaysUsage?
Try to add both keys to the Info.plist:
Privacy - Location When In Use Usage Description
Privacy - Location Always Usage Description
Also, what happens if you implement this method of protocol?
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("\(error.localizedDescription)")
}
Does it print anything? Sorry, I was going to leave a comment, but I don't have enough reputation.
I want to use Background Fetch Location Updates service on my app. But don't show any output my codes here i want your help.
import CoreLocation
class ViewController: UIViewController, UITextFieldDelegate, CLLocationManagerDelegate {
var locationManager:CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
print("didChangeAuthorizationStatus")
switch status {
case .NotDetermined:
print(".NotDetermined")
break
case .Authorized:
print(".Authorized")
self.locationManager.startUpdatingLocation()
break
case .Denied:
print(".Denied")
break
default:
print("Unhandled authorization status")
break
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last as CLLocation!
print("didUpdateLocations: \(location.coordinate.latitude), \(location.coordinate.longitude)")
}
Giving output only
didChangeAuthorizationStatus
.NotDetermined
If it possible i want to take long lat value when new location changes.
Thank you !
I added this to the info.plist file:
<key>NSLocationAlwaysUsageDescription</key>
<string>Your message goes here</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your message goes here</string>
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]