I am trying to get the user location but it doesn't work when the view loads. I have a refresh method that works just fine but that requires the user to tap a refresh button. The user location appears on the map when the view loads but in getLocation(), myLocation is nil. And again, tapping the refresh button that calls refreshLocation() works as expected.
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
mapView.userTrackingMode = .follow
getLocationAuthorizationStatus()
}
Request Authorization
func getLocationAuthorizationStatus() {
print("getLocationAuthorizationStatus()")
if CLLocationManager.authorizationStatus() == .notDetermined {
locationManager.requestWhenInUseAuthorization()
} else if CLLocationManager.authorizationStatus() == .denied {
// Display UIAlertController
let locationDeniedAlert = BasicAlert(title: "", message: "Location services were denied. Please enable location services in Settings.", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default, handler: {
(action) -> Void in
let settingsURL = URL(string: UIApplicationOpenSettingsURLString)
if let url = settingsURL {
// UIApplication.shared.openURL(url)
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
locationDeniedAlert.dismiss(animated: true, completion: nil)
})
locationDeniedAlert.addAction(settingsAction)
self.present(locationDeniedAlert, animated: true, completion: nil)
} else if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
if fromSearch {
fromSearch = false
} else {
getLocation()
}
}
}
Get Location
func getLocation() {
print("getLocation()")
locationManager.startUpdatingLocation()
if locationManager.location != nil {
myLocation = locationManager.location!
if mapView.annotations.count == 1 && mapView.annotations[0] as! MKUserLocation == mapView.userLocation {
retrieveGymsWithLocation()
}
} else {
myLocation = nil
print("location = nil")
}
}
#objc func refreshLocation() {
print("refreshLocation()")
let annotationsToRemove = mapView.annotations
mapView.removeAnnotations(annotationsToRemove)
gyms.removeAll()
imageArrays.removeAll()
gymLocations.removeAll()
getLocationAuthorizationStatus()
}
Location Manager
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
myLocation = locations.last
}
It takes a while for CLLocationManager to determine the current location, depending on gps satellite availability and other kinds of influence. Therefore, you'll simply have to wait a while until the location property is set.
You typically would do this in the delegate method:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
myLocation = locations.last
if mapView.annotations.count == 1 && mapView.annotations[0] as! MKUserLocation == mapView.userLocation {
retrieveGymsWithLocation()
}
}
Related
I have an iOS app that needs to track user's geolocation for a research project. However, the app gets automatically suspended by the iOS after a few hours and the geolocation tracking stops working.
Geofencing is not sufficient for my case as it's not accurate enough.
Is there any way to can prevent the app from getting suspended (unless user manually terminate it)?
One way I thought of is to play a silent music indefinitely, and display the music controls on lockscreen through MPRemoteCommandCenter, like how Spotify works.
Would that keep the app alive? (as I believe Spotify never gets killed unless user manually terminate it?)
I have similar app which uses user location for tracking. Check if you have all these permissions in info.plist. And specifically tell users why you are using location permissions
<key>NSLocationAlwaysUsageDescription</key>
<string>Application needs permission to access your current location.
</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Application needs permission to access your current location.
</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
Here is a part of my code. I have removed the unwanted part so you might have to edit while using it.
import GooglePlaces
import GoogleMaps
class StartRideViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate{
var mapView: GMSMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: Notification.Name.UIApplicationWillResignActive, object: nil)
notificationCenter.addObserver(self, selector: #selector(appMovedToForeGround), name: Notification.Name.UIApplicationDidBecomeActive, object: nil)
}
#objc func appMovedToBackground() {
print("App moved to background!")
print(isStartRide)
if isStartRide == false{
btn_Share.isHidden = true
locationManager.allowsBackgroundLocationUpdates = false
locationManager.stopUpdatingLocation()
}
}
#objc func appMovedToForeGround() {
//getMeRidersData()
}
func initiateLocation(){
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = 1
locationManager.startUpdatingLocation()
//locationManager.startUpdatingHeading()
locationManager.allowsBackgroundLocationUpdates = true
//checkForLocationServices()
checkLocationAuthorizationStatus()
guard let myLatitude = locationManager.location?.coordinate.latitude else{
return
}
guard let myLongitude = locationManager.location?.coordinate.longitude
else{
return
}
showMap(myLatitude:myLatitude, myLongitude:myLongitude)
}
func showMap(myLatitude:Double, myLongitude:Double){
let camera = GMSCameraPosition.camera(withLatitude: myLatitude,
longitude: myLongitude, zoom: 17)
mapView = GMSMapView.map(withFrame: view.bounds, camera: camera)
//mapView = GMSMapView.map(withFrame: CGRect(x: 0, y: 0, width:
self.view.frame.width, height: self.view.frame.height - 250), camera: camera)
mapView?.center = self.view.center
self.view.addSubview(mapView!)
mapView.padding = UIEdgeInsetsMake(150, 0, 80, 0)
mapView.settings.myLocationButton = true
mapView.delegate = self
//mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.isMyLocationEnabled = true
frameForMapView.addSubview(mapView)
}
func checkLocationAuthorizationStatus() {
let status = CLLocationManager.authorizationStatus()
if status == CLAuthorizationStatus.notDetermined{
print("NotDetermined")
locationManager.requestWhenInUseAuthorization()
CLLocationManager.locationServicesEnabled()
locationManager.requestLocation()
}else {
print("Problem with authorization")
}
}
// Handle incoming location events.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location: CLLocation = locations.last!
print("Location: \(location)")
moveMyImageOnMap()
print(isStartRide, gotCounterFromLastRide , counter)
if isStartRide && gotCounterFromLastRide{
updateMyLocationToDataBase()
}
}
// func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
// print(newHeading)
// }
// 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.
case .notDetermined:
print("Location status not determined.")
case .authorizedAlways: fallthrough
case .authorizedWhenInUse:
print("Location status is OK.")
if mapView != nil {
mapView.isMyLocationEnabled = true
}
}
}
// Handle location manager errors.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.stopUpdatingLocation()
print("Error: \(error)")
let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as! String
let msg :String = "You have denied the app to access your location. Please enable the location services in your settings for the app to get the location";
let alertController = UIAlertController(title: "Allow \(appName) to access your location while you are using the app?", message: msg, preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "CANCEL", style: UIAlertActionStyle.default, handler: nil)
let settingsAction = UIAlertAction(title: "SETTINGS", style: .default) { (_) -> Void in
guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
return
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
print("Settings opened: \(success)") // Prints true
})
}
}
alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
self.present(alertController, animated: true, completion: nil)
}
}
I added this code in my viewController
import UIKit
import CoreLocation
import GoogleMaps
class CourseClass2: UIViewController, UITableViewDelegate, UITableViewDataSource, UINavigationControllerDelegate {
#IBOutlet weak var mapView: GMSMapView!
}
and this extension
extension CourseClass2: CLLocationManagerDelegate {
func determineMyCurrentLocation() {
guard currentLocation == nil else {
return
}
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.desiredAccuracy = kCLLocationAccuracyBest
locationManager?.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
manager.stopUpdatingLocation()
print("user latitude = \(userLocation.coordinate.latitude)")
print("user longitude = \(userLocation.coordinate.longitude)")
didReceiveUserLocation(userLocation)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Error \(error)")
errorGettingCurrentLocation(error.localizedDescription)
}
public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse || status == .authorizedAlways {
locationManager?.startUpdatingLocation()
//locationManager.startUpdatingHeading()
} else if status == .denied || status == .restricted {
errorGettingCurrentLocation("Location access denied")
}
}
func errorGettingCurrentLocation(_ errorMessage:String) {
let alert = UIAlertController.init(title: "Error", message: errorMessage, preferredStyle: .alert)
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
}
}
to get the user location. Now i would like to add in the viewDidLoad of my controller a camera like let camera = GMSCameraPosition.camera(withLatitude: , longitude: , zoom: 14) on the user position, but how can i do to use in this line the latitude and longitude of my user current position that i found with my extension?
You need to call locationManager.startUpdatingLocation() in viewDidLoad() where locationManager is CLLocationManager object. As soon as your current location is retrieved, didUpdateLocations delegate method is called where you can set the camera position as follows:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation = locations.last
let location = GMSCameraPosition.camera(withLatitude: userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude, zoom: 16.0)
mapView.animate(to: location)
}
This is a really basic outlay of what I am using...
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
// Call the locationManager class
let LocationManager = CLLocationManager()
// CoreData Delegate
let appDelegate = UIApplication.shared.delegate as! AppDelegate
override func viewDidLoad() {
super.viewDidLoad()
// Conform to Delegate Method
self.LocationManager.delegate = self
// Set required accuracy
self.LocationManager.desiredAccuracy = kCLLocationAccuracyBest
// Blue dot
self.mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// check location services active
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
// check location services
switch CLLocationManager.authorizationStatus() {
case .authorizedAlways:
self.LocationManager.startUpdatingLocation()
case .notDetermined:
self.LocationManager.requestAlwaysAuthorization()
case .authorizedWhenInUse, .restricted, .denied:
let alertController = UIAlertController(
title: "Background Location Access Disabled",
message: "In order to work your location settings need to be set to 'Always'.",
preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
let openAction = UIAlertAction(title: "Open Settings", style: .default) { (action) in
if let url = NSURL(string:UIApplicationOpenSettingsURLString) {
UIApplication.shared.open(url as URL)
}
}
alertController.addAction(openAction)
self.present(alertController, animated: true, completion: nil)
}
}
// Location delegate methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
// get last location
let location = locations.last
print(location!.coordinate.latitude)
// set region
let region = MKCoordinateRegion(center: location!.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
// deploy region to map
self.mapView.setRegion(region, animated: true)
// Map to follow the user
self.mapView.setUserTrackingMode(MKUserTrackingMode.follow, animated: true)
// Show compass on map
self.mapView.showsCompass = true
// save the location data to CoreData
//self.save(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
// end Location updating
self.LocationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Errors: " + error.localizedDescription)
}
}
My issue is that func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation] calls itself over and over again (around 3 times on initial load)...
I am using the .last which AFAIK is meant to pull out the last result in that object.. which it probably is, as with breakpoints inserted it after the first 2 prints it only returns 1 lot of results...
After searching high and low, I am hoping I can get a result by asking the question... Thanks!
Console output of my issue:
When you call startUpdatingLocation() the location manager immediately starts the delivering of location data. The first incoming locations may be way off your actual location, so check the horizontalAccuracy and verticalAccuracy attributes and dismiss locations which are too inaccurate.
It looks like you just want to get a one-shot location, if so try this code:
// Use:
// at class level:
// var manager: LocationOneShotManager?
// in viewDidLoad:
// manager = LocationOneShotManager()
// manager!.fetchWithCompletion {location, error in
// // fetch location or an error
// if let loc = location {
// println(location)
// } else if let err = error {
// println(err.localizedDescription)
// }
// self.manager = nil
// }
import UIKit
import CoreLocation
// possible errors
enum OneShotLocationManagerErrors: Int {
case AuthorizationDenied
case AuthorizationNotDetermined
case InvalidLocation
}
class LocationOneShotManager: NSObject, CLLocationManagerDelegate {
// location manager
private var locationManager: CLLocationManager?
// destroy the manager
deinit {
locationManager?.delegate = nil
locationManager = nil
}
typealias LocationClosure = ((location: CLLocation?, error: NSError?)->())
private var didComplete: LocationClosure?
// location manager returned, call didcomplete closure
private func _didComplete(location: CLLocation?, error: NSError?) {
locationManager?.stopUpdatingLocation()
didComplete?(location: location, error: error)
locationManager?.delegate = nil
locationManager = nil
}
// location authorization status changed
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .AuthorizedWhenInUse:
self.locationManager!.startUpdatingLocation()
case .Denied:
_didComplete(nil, error: NSError(domain: self.classForCoder.description(),
code: OneShotLocationManagerErrors.AuthorizationDenied.rawValue,
userInfo: nil))
default:
break
}
}
internal func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
_didComplete(nil, error: error)
}
internal func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
_didComplete(location, error: nil)
}
// ask for location permissions, fetch 1 location, and return
func fetchWithCompletion(completion: LocationClosure) {
// store the completion closure
didComplete = completion
// fire the location manager
locationManager = CLLocationManager()
locationManager!.delegate = self
// check for description key and ask permissions
if (NSBundle.mainBundle().objectForInfoDictionaryKey("NSLocationWhenInUseUsageDescription") != nil) {
locationManager!.requestWhenInUseAuthorization()
} else if (NSBundle.mainBundle().objectForInfoDictionaryKey("NSLocationAlwaysUsageDescription") != nil) {
locationManager!.requestAlwaysAuthorization()
} else {
fatalError("To use location in iOS8 you need to define either NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in the app bundle's Info.plist file")
}
}
}
My app (1) gets the user's location then (2) parses XML based on that location data. From load, the app works great. But I would like to get updated XML based on a change of location when the user taps the refresh button. I've tried several versions of this but can't get to work. I've included the portion of my code I think is relevant to this question (I think it's a timing issue). On tapping the refresh button, the location updates but the old XML is loaded:
class Myclass: UIPageViewController, UIPageViewControllerDataSource, CLLocationManagerDelegate, NSXMLParserDelegate {
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestWhenInUseAuthorization()
//locationManager.requestLocation()
}
override func viewWillAppear(animated: Bool) {
switch CLLocationManager.authorizationStatus() {
case .AuthorizedWhenInUse, .AuthorizedAlways:
busyAlertController.display()
locationManager.requestLocation()
print("Authorized")
case .NotDetermined:
locationManager.requestWhenInUseAuthorization() // or request always if you need it
print("Not Determined")
case .Restricted, .Denied:
print("Restricted or Denied")
self.dismissViewControllerAnimated(true, completion: nil)
let alertController = UIAlertController(
title: "Background Location Access Disabled",
message: "We need to know your location to show you the correct forecast, please open this app's settings and set location access to 'When in Use' or 'Always'.",
preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
alertController.addAction(cancelAction)
let openAction = UIAlertAction(title: "Open Settings", style: .Default) { (action) in
if let url = NSURL(string:UIApplicationOpenSettingsURLString) {
UIApplication.sharedApplication().openURL(url)
}
}
alertController.addAction(openAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
// MARK: UIPageViewControllerDataSource & UIPageViewControllerDelegate
// MARK: - CLLocationManagerDelegate
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if (status == .AuthorizedAlways) || (status == .AuthorizedWhenInUse) {
locationManager.requestLocation()
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
let lat = "\(location.coordinate.latitude)"
let lon = "\(location.coordinate.longitude)"
let url = baseURL + lat + "&lon=" + lon + suffixURL
guard let urlAsNSURL = NSURL(string: url) else {return}
NWSURL = urlAsNSURL
runParser()
} else {
//TODO:
}
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Error finding location: \(error.localizedDescription)")
showAlert("Location Problem", message: "We're having trouble finding your location, please try again.")
}
//XMLParser Methods
func parserDidEndDocument(parser: NSXMLParser){
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.showVC()
})
}
func runParser() {
guard let url = URL else {
return}
guard let parser = NSXMLParser(contentsOfURL: url) else {return}
parser.delegate = self
parser.parse()
}
#IBAction func refresh(sender: UIBarButtonItem) {
locationManager.requestLocation()
//runParser()
}
}
The locations array which was passed into locationManager:didUpdateLocations: may contain more than one location in case updates were deferred or multiple locations arrived before they could be delivered.
Since it is organized in the order in which the updates occurred, the most recent location update is at the end of the array.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
...
}
}
The problem was that I wasn't clearing out a variable (array) after the NSXMLParser was done, and so I was appending over the stale data, yet since the stale data was first it was displaying in my UI and made it VERY hard to detect the problem until I printed to the console and saw the multiple arrays. I've done something similar before so note to anyone implementing NSXMLParser: make sure that you clear out the variable that you are using to store data in didEndElement.
When I run the code, the window pops asking for permission to use location but disappears almost immediately, not giving the user a chance to click "Allow". Is there a way to force this action before proceeding?
import UIKit
import MapKit
import CoreLocation
class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate{
var map:MKMapView?
var manager:CLLocationManager!
convenience init(frame:CGRect){
self.init(nibName: nil, bundle: nil)
self.view.frame = frame
self.map = MKMapView(frame: frame)
self.map!.delegate = self
self.view.addSubview(self.map!)
}
override func viewDidLoad() {
super.viewDidLoad()
// Core Location
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
}
func locationManager(manager: CLLocationManager!,
didChangeAuthorizationStatus status: CLAuthorizationStatus){
print("The authorization status of location services is changed to: ")
switch CLLocationManager.authorizationStatus(){
case .Denied:
println("Denied")
case .NotDetermined:
println("Not determined")
case .Restricted:
println("Restricted")
default:
println("Authorized")
}
}
func displayAlertWithTitle(title: String, message: String){
let controller = UIAlertController(title: title,
message: message,
preferredStyle: .Alert)
controller.addAction(UIAlertAction(title: "OK",
style: .Default,
handler: nil))
presentViewController(controller, animated: true, completion: nil)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if CLLocationManager.locationServicesEnabled(){
switch CLLocationManager.authorizationStatus(){
case .Denied:
displayAlertWithTitle("Not Determined",
message: "Location services are not allowed for this app")
case .NotDetermined:
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
case .Restricted:
displayAlertWithTitle("Restricted",
message: "Location services are not allowed for this app")
default:
println("Default")
}
} else {
println("Location services are not enabled")
}
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
var userLocation:CLLocation = locations[0] as! CLLocation
var latitude:CLLocationDegrees = userLocation.coordinate.latitude
var longitude:CLLocationDegrees = userLocation.coordinate.longitude
var latDelta:CLLocationDegrees = 1.0
var lonDelta:CLLocationDegrees = 1.0
var span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
var location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
var region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
map!.setRegion(region, animated: true)
manager.stopUpdatingLocation()
}
Please try this:
import UIKit
import GoogleMaps
import CoreLocation
class StartViewController: UIViewController,CLLocationManagerDelegate,GMSMapViewDelegate {
var locationManager: CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
setupLocationManager()
}
func setupLocationManager() {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
locationHandler()
}
func locationHandler() {
if CLLocationManager.locationServicesEnabled() == true {
if (CLLocationManager.authorizationStatus() == .denied) {
// The user denied authorization
} else if (CLLocationManager.authorizationStatus() == .authorizedAlways) {
// The user accepted authorization
} else if (CLLocationManager.authorizationStatus() == .notDetermined){
// The user not determiend authorization
}else if (CLLocationManager.authorizationStatus() == .authorizedWhenInUse){
// In use
}else{ }
}else{
//Access to user location permission denied!
}
}
}//class
Be successful.
It's because you're calling manager.startUpdatingLocation() before you get the result from the manager.requestWhenInUseAuthorization(). Even though you call requestWhenInUseAuthorization, you're updating the user's location before you ever get the result of that method (I had the exact same question as you, actually!)
The answer to that question explains the solution well. Basically, you'll need to implement the locationManager:didChangeAuthorizationStatus delegate method, which is called any time the authorization status changes based on user input. If the user did authorize tracking, then you can call manager.startUpdatingLocation().
Also, for a Swift example of how to implement these methods, take look at this guide.