Update location when user allows location tracking - ios

I'm trying to animate where the user is when they accepts location tracking. The Code works when they already have accepted location tracking and then loads the view but I would like to have the view reload when they press accept on location tracking.
override func viewDidLoad() {
super.viewDidLoad()
//Prepare to get User
if CLLocationManager.authorizationStatus() != .authorizedAlways {
// May need to change to support location based notifications
locationManager.requestAlwaysAuthorization()
print("hello")
mapView.setVisibleMapRect(mapView.visibleMapRect, animated: true)
}else {
locationManager.startUpdatingLocation()
}
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
mapView.delegate = self
}
Animated to user location Code
//Get user location
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//Show the map at the users current location
let location = locations[0]
let span:MKCoordinateSpan = MKCoordinateSpanMake(0.02,0.02 )
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
mapView.setRegion(region, animated: true)
self.mapView.showsUserLocation = true
locationManager.stopUpdatingLocation()
}

You can use:
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
locationManager.requestAlwaysAuthorization()
break
case .authorizedWhenInUse:
locationManager.startUpdatingLocation()
break
case .authorizedAlways:
locationManager.startUpdatingLocation()
break
default:
break
}
}

All methods used to update locations in CLLocationManager are asynchronous, so there might be a delay from the user allowing location access to the location update actually happening regardless of the implementation of your code.
However, by calling CLLocationManager().requestLocation() inside locationManager(didChangeAuthorizationStatus) you can ensure that you receive a location update as close as possible to the acceptance of location usage.
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
locationManager.requestAlwaysAuthorization()
case .authorizedWhenInUse:
locationManager.requestLocation()
case .authorizedAlways:
locationManager.requestLocation()
default:
break
}
}
This will automatically call your CLLocationManagerDelegate method as soon as the asynchronous requestLocation function finishes execution.

Related

swift user location - update if move

So I have been able to get the users location via the following code.
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status != .authorizedWhenInUse {return}
print("test LOCATION BELOW")
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
let locValue: CLLocationCoordinate2D = manager.location!.coordinate
print("UUID: \(String(describing: uuid)) locations = \(locValue.latitude) \(locValue.longitude)")
}
However I want to watch the users location and if they move update their location.
I am wondering how do I get this code to keep checking for the users location?
My
override func viewDidLoad(){
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()}
I get it popping up the request and I approve it but it does not run the code
Here is how you can get the location data. The code is similar to yours but with a bit of change and additions.
First check if you already have user's permission to get their location data.
func isLocationServicesEnabled() -> Bool {
if CLLocationManager.locationServicesEnabled() {
switch(CLLocationManager.authorizationStatus()) {
case .notDetermined, .restricted, .denied:
return false
case .authorizedAlways, .authorizedWhenInUse:
return true
#unknown default:
return false
}
}
return false
}
If this method returns false you can ask for authorization.
// Initialize manager in your viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.delegate = self
// Do other stuff
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Check for auth
if isLocationServicesEnabled() {
locationManager.startUpdatingLocation()
} else {
locationManager.requestWhenInUseAuthorization()
}
// Do other stuff
}
Finally in your CLLocationManagerDelegate implementation get the coordinates.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last?.coordinate else { return }
// Use location.latitude and location.longitude here
// If you don't want to receive any more location data then call
locationManager.stopUpdatingLocation()
}
First, you have to check that you have user's permission to get their location data
func checkLocationServicesAuthorization() -> Bool {
if CLLocationManager.locationServicesEnabled() {
switch CLLocationManager.authorizationStatus() {
case .notDetermined:
return false
case .restricted, .denied:
//code for open settings screen in user’s phone
return false
case .authorizedWhenInUse, .authorizedAlways:
return true
default:
return false
}
} else {
//code for open settings screen in user’s phone
}
return false
}
And
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if checkLocationServicesAuthorization() {
locationManager.startUpdatingLocation()
} else {
locationManager.requestWhenInUseAuthorization()
}
}
You can use delegate method didUpdateLocations of CLLocationManagerDelegate and don't forgot to connect delegate yourLocationManager.delegate = self
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
// Call stopUpdatingLocation() to stop listening for location updates, other wise this function will be called every time when user location changes.
// yourLocationManager.stopUpdatingLocation()
guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
let latitude = String.init(userLocation.coordinate.latitude)
let longitude = String.init(userLocation.coordinate.longitude)
print("\(latitude), \(longitude)")
}

Get current location in ios 9 using Google maps sdk

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>

swift - didUpdateLocations Not Being Called

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.

Swift background fetch location updates with Core Location

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>

Location Manager not updating location in swift. AlertView disappears

I want to get location inside a custom delegate in swift. Note that this worked perfectly 2 hours ago. The major problem is that the Location authorization alertView disappears by its own before I get to Allow it. So i tried to go within settings and allow it but it does not work. Why is the alertView disappearing by it self and why even though I allowed it through the settings I still cannot get an update? I added the correct key in the plist and also added the delegate and CoreLocation framework in the file. Also note that the didFail is not called at any point. Any advise would be appreciated
func getLocation(){
println("called")
let locationManager:CLLocationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
let status = CLLocationManager.authorizationStatus()
println(status.rawValue)
if(status != CLAuthorizationStatus.Authorized) {
locationManager.requestWhenInUseAuthorization()
println("called2")
}else{
locationManager.startUpdatingLocation()
println("allowed and updating")
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
println("updating")
var locationArray = locations as NSArray
var locationObj = locationArray.lastObject as CLLocation
println(locationObj)
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println(error)
}
func locationManager(manager: CLLocationManager!,
didChangeAuthorizationStatus status: CLAuthorizationStatus) {
var shouldIAllow = false
println(status)
switch status {
case CLAuthorizationStatus.Restricted:
println("Restricted Access to location")
case CLAuthorizationStatus.Denied:
println("User denied access to location")
case CLAuthorizationStatus.NotDetermined:
println("Status not determined")
default:
println("Allowed to location Access")
shouldIAllow = true
}
if (shouldIAllow == true) {
manager.startUpdatingLocation()
} else {
println("Denied access: \(status)")
}
}
Create a property from locationManager , because this way it is destroyed after you run your method. And don't forget to setup its delegate for example in viewDidLoad.

Resources