How to sync location when app is in background - ios

I want to send user current Location to a server in every 15 minutes. When the app is in the foreground the timer is running but when the app is in background timer is not running. I searched a lot but did not find any solution. Can you please tell me what I do. I am using below code for background location sync but it's not working.
var locationManager = CLLocationManager()
var currentLocation: CLLocation?
var timer : Timer?
var backgroundTaskIdentifier: UIBackgroundTaskIdentifier?
func getCurrentLocation()
{
// Do any additional setup after loading the view, typically from a nib.
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
//
backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: {
UIApplication.shared.endBackgroundTask(self.backgroundTaskIdentifier!)
})
let timer = Timer.scheduledTimer(withTimeInterval: 10.0, repeats: true) { (timer) in
self.locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
print("locations = \(locations)")
if let location = locations.last
{
print("location\(String(describing: location.coordinate))")
currentLocation = location
locationManager.stopUpdatingLocation()
}
}

I am also having similar kind of requirement but time interval is 5minutes.
May be your app in idle for longer time(15 minutes) that's y OS is not updating your locations.
Try to keep shorter interval and try it will work.

Did you handle location update from AppDelegate for application state? If not you can update your code with below methods in AppDelegate.
var locationManager = CLLocationManager()
func doBackgroundTask() {
DispatchQueue.global(qos: .background).async {
self.beginBackgroundUpdateTask()
self.StartupdateLocation()
RunLoop.current.run()
}
}
func beginBackgroundUpdateTask() {
backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
self.endBackgroundUpdateTask()
})
}
func endBackgroundUpdateTask() {
UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
self.backgroundUpdateTask = UIBackgroundTaskInvalid
}
func StartupdateLocation() {
locationManager.startUpdatingLocation()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.requestAlwaysAuthorization()
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
}
Call the method when application is going in background state.
func applicationWillResignActive(_ application: UIApplication) {
self.doBackgroundTask()
}
This methods will help you for getting update of location when app is in background.
You can take a look at this link if you face any other difficulties. Update location in Background

Related

Retrieve current location when application is in background

I've built an application where you can press a start button. Once the button is pressed the application will get user location every 10 second all the way till the stop button is pressed. When I leave the application or if the screen gets black, it will NOT get any more locations till I re-enter the application.
So, I'm currently trying to update the locations when the application is minimized. (I guess it's called in the background?), and also when the screen turns black. But my questions is:
Should I write this code in the AppDelegate?, if so. How can I know
if the button was pressed or not?
Where exactly in the AppDelegate should I add the code? And how can
I pass the locations back to the correct ViewController? (Since I
cannot make any prepare for segue from AppDelegate)
If you know the answers of this questions, please do not hesitate to answer them. :) I would really appreciate it!
The best way to get user's location in background is to use the Significant-Change Location Service according to apple's documentation put this func in your class:
func startReceivingSignificantLocationChanges() {
let authorizationStatus = CLLocationManager.authorizationStatus()
if authorizationStatus != .authorizedAlways {
// User has not authorized access to location information.
return
}
if !CLLocationManager.significantLocationChangeMonitoringAvailable() {
// The service is not available.
return
}
locationManager.delegate = self
locationManager.startMonitoringSignificantLocationChanges()
}
and also this func:
func locationManager(_ manager: CLLocationManager, didUpdateLocations
locations: [CLLocation]) {
let lastLocation = locations.last!
// Do something with the location.
}
so you just need to call startReceivingSignificantLocationChanges() inside your button and it will call locationManager(_ manager: CLLocationManager,didUpdateLocations locations: [CLLocation]), so do what you want with the location there.
Remember to ask permission to use location and to stop tracking with locationManager.stopMonitoringSignificantLocationChanges()
Take location permission for Always Allow
Set location manager for allowsBackgroundLocationUpdates true
from the above way you can get location in every location changes store this information and it send to server. Below is the sample code
typealias LocateMeCallback = (_ location: CLLocation?) -> Void
/*
LocationTracker to track the user in while navigating from one place to other and store new locations in locations array.
**/
class LocationTracker: NSObject {
static let shared = LocationTracker()
var lastLocation: CLLocation?
var locations: [CLLocation] = []
var previousLocation: CLLocation?
var isPreviousIsSameAsCurrent: Bool {
if let previous = previousLocation, let last = lastLocation {
return previous == last
}
return false
}
var isAggressiveModeOn = false
var locationManager: CLLocationManager = {
let locationManager = CLLocationManager()
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = true
locationManager.activityType = .automotiveNavigation
return locationManager
}()
var locateMeCallback: LocateMeCallback?
var isCurrentLocationAvailable: Bool {
if lastLocation != nil {
return true
}
return false
}
func enableLocationServices() {
locationManager.delegate = self
switch CLLocationManager.authorizationStatus() {
case .notDetermined:
// Request when-in-use authorization initially
locationManager.requestWhenInUseAuthorization()
case .restricted, .denied:
// Disable location features
print("Fail permission to get current location of user")
case .authorizedWhenInUse:
// Enable basic location features
enableMyWhenInUseFeatures()
case .authorizedAlways:
// Enable any of your app's location features
enableMyAlwaysFeatures()
}
}
func enableMyWhenInUseFeatures() {
locationManager.startUpdatingLocation()
locationManager.delegate = self
escalateLocationServiceAuthorization()
}
func escalateLocationServiceAuthorization() {
// Escalate only when the authorization is set to when-in-use
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
locationManager.requestAlwaysAuthorization()
}
}
func enableMyAlwaysFeatures() {
enableCoarseLocationFetch()
locationManager.startUpdatingLocation()
locationManager.delegate = self
}
// Enable Rough Location Fetch
func enableCoarseLocationFetch() {
isAggressiveModeOn = false
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.distanceFilter = 100
}
// Enable Aggressive Location Fetch
func enableAggressiveLocationFetch() {
isAggressiveModeOn = true
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = 10
}
func locateMe(callback: #escaping LocateMeCallback) {
self.locateMeCallback = callback
if lastLocation == nil {
enableLocationServices()
} else {
callback(lastLocation)
}
}
func startTracking() {
enableLocationServices()
}
func stopTracking() {
locationManager.stopUpdatingLocation()
}
func resetPreviousLocation() {
previousLocation = nil
}
private override init() {}
}
extension LocationTracker: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
guard let location = locations.first else { return }
guard -location.timestamp.timeIntervalSinceNow < 120, // Validate only location fetched recently
location.horizontalAccuracy > 0, // Validate Horizontal Accuracy - Ve means Invalid
location.horizontalAccuracy < 200 // Validate Horizontal Accuracy > 100 M
else {
print("invalid location received OR ignore old (cached) updates")
return
}
self.locations.append(location)
lastLocation = location
if let activeRide = RideManager.shared.activeRide,
let _ = AccessTokenHelper.shared.accessToken,
let activeRideId = activeRide.ride_id,
let type = activeRide.rideStatusTypeOptional,
type == .started {
//Store Location For A particular Ride after Start
LocationUpdater.shared.saveInDataBase(rideId: activeRideId, locations: [location])
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
enableLocationServices()
}
}
/*
This class having responsibility of Updating the location on server after n second and update path after n second.
**/
class LocationTimer {
static let time: Double = 30
}
/*
class to update locations to server after nth second
**/
class LocationUpdater: NSObject {
static let shared = LocationUpdater(n: Double(LocationTimer.time), tracker: LocationTracker.shared)
let n: Double
private let tracker: LocationTracker
var timer: Timer! = nil
init(n: Double, tracker: LocationTracker) {
self.n = n
self.tracker = tracker
super.init()
}
func startUpdater() {
self.timer?.invalidate()
self.timer = nil
self.timer = Timer.scheduledTimer(timeInterval: n, target: self, selector: #selector(updateLocationsToServer), userInfo: nil, repeats: true)
self.timer.fire()
}
func stopUpdater() {
self.timer?.invalidate()
self.timer = nil
}
#objc func updateLocationsToServer() {
// update to server
}
}
// usage
LocationTracker.shared.startTracking()
LocationUpdater.shared.startUpdater()

Send Location of User in Background Swift

I am building an app where the user clicks a button and for 60mins (or any amount of time) we keep track of them by uploading their location to a server. Currently we are using 'Did Update Locations' function to send the users location to firebase in real-time.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
This system works but it spams the server sending the location of the user to the server once every second.
This is too much data and we would only need to send the users location to the server once every 10-30 seconds.
What can we do send the users location once every 10-30 seconds?
class ViewController: UIViewController, CLLocationManagerDelegate {
private var locman = CLLocationManager()
private var startTime: Date? //An instance variable, will be used as a previous location time.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let loc = locations.last else { return }
let time = loc.timestamp
guard var startTime = startTime else {
self.startTime = time // Saving time of first location, so we could use it to compare later with second location time.
return //Returning from this function, as at this moment we don't have second location.
}
let elapsed = time.timeIntervalSince(startTime) // Calculating time interval between first and second (previously saved) locations timestamps.
if elapsed > 30 { //If time interval is more than 30 seconds
print("Upload updated location to server")
updateUser(location: loc) //user function which uploads user location or coordinate to server.
startTime = time //Changing our timestamp of previous location to timestamp of location we already uploaded.
}
}
import UIKit
import CoreLocation
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,CLLocationManagerDelegate {
var window: UIWindow?
var locationManager = CLLocationManager()
var backgroundUpdateTask: UIBackgroundTaskIdentifier!
var bgtimer = Timer()
var latitude: Double = 0.0
var longitude: Double = 0.0
var current_time = NSDate().timeIntervalSince1970
var timer = Timer()
var f = 0
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.doBackgroundTask()
return true
}
func applicationWillResignActive(_ application: UIApplication) {
}
func applicationWillEnterForeground(_ application: UIApplication) {
print("Entering foreBackground")
}
func applicationDidBecomeActive(_ application: UIApplication) {
}
func applicationWillTerminate(_ application: UIApplication) {
}
func applicationDidEnterBackground(_ application: UIApplication) {
print("Entering Background")
// self.doBackgroundTask()
}
func doBackgroundTask() {
DispatchQueue.main.async {
self.beginBackgroundUpdateTask()
self.StartupdateLocation()
self.bgtimer = Timer.scheduledTimer(timeInterval:-1, target: self, selector: #selector(AppDelegate.bgtimer(_:)), userInfo: nil, repeats: true)
RunLoop.current.add(self.bgtimer, forMode: RunLoopMode.defaultRunLoopMode)
RunLoop.current.run()
self.endBackgroundUpdateTask()
}
}
func beginBackgroundUpdateTask() {
self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
self.endBackgroundUpdateTask()
})
}
func endBackgroundUpdateTask() {
UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
self.backgroundUpdateTask = UIBackgroundTaskInvalid
}
func StartupdateLocation() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.requestAlwaysAuthorization()
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Error while requesting new coordinates")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
self.latitude = locValue.latitude
self.longitude = locValue.longitude
f+=1
print("New Coordinates: \(f) ")
print(self.latitude)
print(self.longitude)
}
#objc func bgtimer(_ timer:Timer!){
sleep(2)
/* if UIApplication.shared.applicationState == .active {
timer.invalidate()
}*/
self.updateLocation()
}
func updateLocation() {
self.locationManager.startUpdatingLocation()
self.locationManager.stopUpdatingLocation()
}}
I added the sleep function to delay of calling the location and send the information to server
Since this is running in both the app is active and goes to background. If you want only background process, remove or comment the function self.doBackgroundTask() from didFinishLaunchingWithOptions and remove the comment for self.doBackgroundTask() in the applicationdidEnterBackground. And then remove the comment in the function bgtimer(), since the background process has to stop once the app comes to active state.
Apps normally get suspended (no longer get CPU time) a moment after being moved to the background. You can ask for extra background time, but the system only gives you 3 minutes.
Only a very limited class of apps are allowed to run in the background for longer than that. Mapping/GPS applications are one of those categories. However, your app is not a mapping/GPS application, so I doubt if Apple would approve it.
Bottom line: I think you might be out of luck running your location queries for more than 3 minutes.
EDIT:
As Paulw11 points out, you can use the significant location change service to get location updates when the device moves by large distances.

Swift - Location Prompt not happening soon enough

I am building a location-based app that lists nearby coffee houses. App keeps crashing on first build on device because location keeps returning as nil.
This is because the Privacy - Location prompt isn't happening soon enough, even though though the request is earlier in the code. After I close the app after it crashes, that's when I'm prompted to allow my location.
I have three onboarding screens, and when I get to this tableviewcontroller, that's when it crashes.
If I go into Settings > Privacy > Location and manually enable location services, the app works great.
Here's my code (I removed a ton of unnecessary stuff):
import UIKit
import MapKit
import CoreLocation
class ShopTableViewController: UITableViewController, CLLocationManagerDelegate {
#IBAction func filterBack(_ sender: Any) {
getLocale()
shops.sort() { $0.distance < $1.distance }
shops.removeAll()
loadShops()
sortList()
}
//MARK: Properties
var shops = [CoffeeShop]()
var filteredShops = [CoffeeShop]()
var objects: [CoffeeShop] = []
var locationManager = CLLocationManager()
func checkLocationAuthorizationStatus() {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
locationManager.requestWhenInUseAuthorization()
}
}
var currentLocation = CLLocation!.self
var userLatitude:CLLocationDegrees! = 0
var userLongitude:CLLocationDegrees! = 0
var locValue:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 1.0, longitude: 1.0)
var refresher: UIRefreshControl! = UIRefreshControl()
func getLocale() {
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
self.locationManager.startMonitoringSignificantLocationChanges()
userLatitude = self.locationManager.location?.coordinate.latitude
userLongitude = self.locationManager.location?.coordinate.longitude
print("\(userLatitude), \(userLongitude)")
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager = CLLocationManager()
/// self.locationManager.requestWhenInUseAuthorization()
checkLocationAuthorizationStatus()
self.locationManager.delegate = self
self.locationManager.startUpdatingLocation()
if CLLocationManager.locationServicesEnabled()
{
getLocale()
}
let locValue = self.locationManager.location?.coordinate
noHeight()
loadShops()
sortList()
print("\(locValue?.latitude), \(locValue?.longitude)")
refresher = UIRefreshControl()
refresher.addTarget(self, action: #selector(ShopTableViewController.handleRefresh), for: UIControlEvents.valueChanged)
if #available(iOS 10, *) {
shopTable.refreshControl = refresher
} else {
shopTable.addSubview(refresher)
}
}
}
What am I doing wrong?
requestWhenInUseAuthorization() is an asynchronous method, so your method that wraps it checkLocationAuthorizationStatus() is also async.
However, in your viewDidLoad, you call
checkLocationAuthorizationStatus()
self.locationManager.delegate = self
self.locationManager.startUpdatingLocation()
This is triggering the locationManager to start before it is authorized. Take a look here at this (somewhat old) link http://nshipster.com/core-location-in-ios-8/
Example
Be sure to conform to CLLocationManagerDelegate
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager = CLLocationManager()
self.locationManager.delegate = self
if CLLocationManager.authorizationStatus() == .notDetermined {
locationManager.requestWhenInUseAuthorization()
} else if CLLocationManager.authorizationStatus() == . authorizedWhenInUse {
startTrackingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedAlways || status == .authorizedWhenInUse {
startTrackingLocation()
// ...
}
}
func startTrackingLocation() {
locationManager.startUpdatingLocation()
getLocale()
//not clear which of these methods require location
let locValue = self.locationManager.location?.coordinate
noHeight()
loadShops()
sortList()
print("\(locValue?.latitude), \(locValue?.longitude)")
}
You need to wait for the authorization response before using location services.
What you are doing now is requesting the authorization and the immediately starting location services. You need to be sure, the app is authorized before getting location.

Location manager stops working after reboot swift ios

I am trying to use location manager in my application. I set the code as I saw in many posts and examples and everything is working fine, and I get the location manager to show the current location as set in the simulator. I then change the location in the simulator and my app gets the new location.
I then reboot my machine, and restart my application, but the location manager stops working. I tried to change the code from using addObserver() to using didUpdateLocations, and sometimes I manage to restart the location manager to work. But when I reboot the machine it stops working again. I tried resetting the simulator and authorizing again the app to get location updates, but with no success. In all cases my app prints that it has authorization to get location update but it does not work. I also tried cleaning the app and rebuilding it, but with no success.
Below are the 2 versions of the code I use.
CODE with addObserver
class TViewController: UIViewController, GMSMapViewDelegate, CLLocationManagerDelegate {
var myLocation: CLLocation?
var locationManager = CLLocationManager()
#IBOutlet weak var mapView: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
mapView!.settings.myLocationButton = true
}
// get updates of myLocation
override func observeValueForKeyPath(keyPath: String?,
ofObject object: AnyObject?,
change: [String : AnyObject]?,
context: UnsafeMutablePointer<Void>)
{
myLocation = change![NSKeyValueChangeNewKey] as? CLLocation
print("in newlocation = \(myLocation)")
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == CLAuthorizationStatus.AuthorizedWhenInUse {
print("in myLocation is authorized")
locationManager.startUpdatingLocation()
mapView!.myLocationEnabled = true
mapView!.addObserver(self, forKeyPath: "myLocation", options: NSKeyValueObservingOptions.New, context: nil)
}
}
}
CODE with didUpdateLocations
extension TViewController: CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == .AuthorizedWhenInUse {
print("in myLocation extension is authorized")
isLocationAvailable = true
locationManager.startUpdatingLocation()
mapView.myLocationEnabled = true
mapView.settings.myLocationButton = true
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
myLocation = locations.first
print("in newlocation extension = \(myLocation)")
mapView.camera = GMSCameraPosition(target: myLocation!.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)
}
class TViewController: UIViewController, GMSMapViewDelegate {
var myLocation: CLLocation?
var locationManager = CLLocationManager()
#IBOutlet weak var mapView: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
mapView!.settings.myLocationButton = true
}

Swift - Trying to get current location [duplicate]

This question already has answers here:
Get User's Current Location / Coordinates
(16 answers)
Closed 6 years ago.
I am trying to get the long and lat of my users locations, I have done the following:
imported Core Location
import CoreLocation
Add Core Location Delegate
class ViewController: UIViewController, CLLocationManagerDelegate, AVCaptureMetadataOutputObjectsDelegate, DTDeviceDelegate {
defined this variable:
var locationManager: CLLocationManager!
and then added this method:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0]
let long = userLocation.coordinate.longitude;
let lat = userLocation.coordinate.latitude;
print(long, lat)
//Do What ever you want with it
}
but the location does not get printed, my method does not even get it.
I add the items to use Core Location to my plist and the app ask me to use the location services when I first run it. But now location is getting printed....what am I doing wrong?
Maybe you forgot to set value for the delegate
In your viewDidLoad() add this:
if CLLocationManager.locationServicesEnabled() {
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
mapView.showsUserLocation = true
}
Use this Code,
declare locationManager
var locationManager = CLLocationManager()
Set the Delegate in viewDidLoad, shown below code,
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
if CLLocationManager.authorizationStatus() == .NotDetermined {
self. locationManager.requestWhenInUseAuthorization()
}
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
Add this in viewdidload,
if (CLLocationManager.locationServicesEnabled())
{
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
if ((UIDevice.currentDevice().systemVersion as NSString).floatValue >= 8)
{
locationManager.requestWhenInUseAuthorization()
}
locationManager.startUpdatingLocation()
}
else
{
#if debug
println("Location services are not enabled");
#endif
}
Then add this two delegate method to get location,
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!)
{
locationManager.stopUpdatingLocation()
if ((error) != nil)
{
print(error)
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
{
var locationArray = locations as NSArray
var locationObj = locationArray.lastObject as! CLLocation
var coord = locationObj.coordinate
print(coord.latitude)
print(coord.longitude)
}
This way you will get your current location.
You neeed to initialize the locationManageger and enable the location flag in xcode also, it appaear bottom of the xcode
self.locationManager = CLLocationManager()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
if #available(iOS 8.0, *) {
if Bundle.main.infoDictionary?["NSLocationAlwaysUsageDescription"] != nil {
self.locationManager.requestAlwaysAuthorization()
}
else {
self.locationManager.requestWhenInUseAuthorization()
}
}
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.startUpdatingLocation()
You can add this code to your viewDidLoad() method:
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
This will call the locationManagers didUpdate delegate-methods if location services are available for your app

Resources