How to update background location of user within specific time interval using swift 4 iOS? - ios

I am working on an app. where I am updating a background location of a user. and I want to update that location within a specific time interval. I have searched a lot. but did not get any solution. please help me out. Here my code below. Thanks in advance.
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)")
self.labelLat.text = "\(userLocation.coordinate.latitude)"
self.labelLongi.text = "\(userLocation.coordinate.longitude)"
DataBaseFunctions.sharedInstance.saveUserDetail(dataToInsert: userLocation)
}

This is in Swift-NOW,
You can use Timer for didUpdateLocation with
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.delegate = self
locationManager.startUpdatingLocation()
var timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.updateLocation), userInfo: nil, repeats: true)
func updateLocation() {
let location: CLLocation = locationManager.location
// Your code
}
// MARK: - CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// Your code
}

Related

Is that possible to receive Location even when app is not running in Swift

I am making an app that trace all the trips made by a user.
The app works perfectly when it is in background or in foreground but I am looking for a way to get it worked even if the app is not running.
I followed exactly this answer : Receiving Location even when app is not running in Swift
But this doesn't work as expected.
I have two property in my AppDelegate
var lastLocation:CLLocation?
//And a location manager
var locationManager = CLLocationManager()
In my DidFinishLaunchingWithOptions I configure the CLLocationManager
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
In my applicationWillTerminate :
lastLocation = HomeController.locations.last
createRegion(location: lastLocation)
Here is the rest :
func createRegion(location:CLLocation?) {
if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
let coordinate = CLLocationCoordinate2DMake((location?.coordinate.latitude)!, (location?.coordinate.longitude)!)
let regionRadius = 50.0
let region = CLCircularRegion(center: CLLocationCoordinate2D(
latitude: coordinate.latitude,
longitude: coordinate.longitude),
radius: regionRadius,
identifier: "aabb")
region.notifyOnExit = true
region.notifyOnEntry = true
//Send your fetched location to server
UserDefaults.standard.set(UserDefaults.standard.integer(forKey: "nbLocNotrunning") + 1, forKey: "nbLocNotrunning")
//Stop your location manager for updating location and start regionMonitoring
self.locationManager.stopUpdatingLocation()
self.locationManager.startMonitoring(for: region)
} else {
print("System can't track regions")
}
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
print("Entered Region")
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
print("Exited Region")
locationManager.stopMonitoring(for: region)
//Start location manager and fetch current location
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if UIApplication.shared.applicationState != .inactive {
} else {
//App is in BG/ Killed or suspended state
//send location to server
// create a New Region with current fetched location
let location = locations.last
lastLocation = location
//Make region and again the same cycle continues.
self.createRegion(location: lastLocation)
}
}
I wonder where the mistake can come from and why I never enter in the function didExitRegion.
For now, I just increment a variable in UserDefaut "nbLocNotrunning" in order to know how many times I leave a region but this number never increase when I stop my app.

iOS geolocation, Code works differently when initialization and declaration happen together

In iOS geolocation, the code works if the locationManager is declared and initialized separately, however it does not work if it is declared and initialized at the same time. Why is it so? The following is the working code sample:-
var locationManager : CLLocationManager!
func initLocManager() {
locationManager=CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.activityType = .automotiveNavigation
locationManager.distanceFilter = 10.0
}
func retrieveLocation(){
initLocManager()
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for location in locations {
print("Long \(location.coordinate.longitude)")
print("Lati \(location.coordinate.latitude)")
}
}
whereas the following code does not work:-
var locationManager = CLLocationManager()
func initLocManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.activityType = .automotiveNavigation
locationManager.distanceFilter = 10.0
}
func retrieveLocation(){
initLocManager()
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for location in locations {
print("Long \(location.coordinate.longitude)")
print("Lati \(location.coordinate.latitude)")
}
}
Another way:
Create new file with this code:
import UIKit
import CoreLocation
class LocationManager: CLLocationManager, CLLocationManagerDelegate {
static let shared = LocationManager()
public var currentLocation = CLLocation() {
didSet {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: LocationManager.LocationUpdatedNotification), object: self, userInfo: nil)
}
}
static let LocationUpdatedNotification: String = "LocationUpdate"
private override init() {
super.init()
self.delegate = self
self.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
self.activityType = .automotiveNavigation
self.distanceFilter = 10.0
self.requestAlwaysAuthorization()
self.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let lastLocation = locations.last {
currentLocation = lastLocation
}
}
}
In AppDelegate.swift
_ = LocationManager.shared // Add this line to func didFinishLaunchingWithOptions
Now you can get current user location using this code:
LocationManager.shared.currentLocation
Also you can subscribe for LocationUpdate notification anywhere in your project.

fatal error: unexpectedly found nil while unwrapping an Optional value when getting Location?

I am developing an app using swift I want to fetch current location of the user and want to show in google map so I wrote my code in my class I have included all the functions and methods (i.e) added and imported frameworks core location and also updated plist but I can't able to fetch current location rotationally some time I get the location but some time it crashed.
Here is the code what I am tried.
import CoreLocation
class HomeViewController: UIViewController, CLLocationManagerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.startUpdatingLocation()
let location: CLLocation? = locationManager.location
let coordinate: CLLocationCoordinate2D? = location?.coordinate ----> App crossed this line then it will crashed
print(coordinate!)
print(coordinate!.latitude)
print(coordinate!.longitude)
strForCurLatitude = "\(coordinate!.latitude)"
strForCurLongitude = "\(coordinate!.longitude)"}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
print("User allowed us to access location")
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Error while get location \(error)")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
locationManager.startUpdatingLocation()
let locationNew = locations.last
let coordinateNew: CLLocationCoordinate2D? = locationNew?.coordinate
strForCurLatitude = "\(coordinateNew!.latitude)"
strForCurLongitude = "\(coordinateNew!.longitude)"
strForLat=strForCurLatitude;
strForLong=strForCurLongitude;
print("User's Latitude is: \(Double(strForLat!)!)")
print("User's Longitude is: \(Double(strForLong!)!)")
self.locationManager.startUpdatingLocation()
}
Remove this from ViewDidLoad because you can not get location in viewDidLoad.
let location: CLLocation? = locationManager.location
let coordinate: CLLocationCoordinate2D? = location?.coordinate
print(coordinate!)
print(coordinate!.latitude)
print(coordinate!.longitude)
strForCurLatitude = "\(coordinate!.latitude)"
strForCurLongitude = "\(coordinate!.longitude)"
In CLLocationManager's following method best for getting location
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
make a reference to CLLocationManager as variable, like this:
class HomeViewController {
var locationManager = CLLocationManager()
viewDidLoad() {
super.viewDidLoad()
}
// rest of code
}
in this case Location Manager should works properly.

How to check if locationManager has updated current location?

I would like to show user's current location on startup, and then keep tracking their location but stop centring on the current location. My idea is to centre on the current location in viewDidLoad(), but I don't know how to wait for locationManager to update the current location before centring. Here are the relevant parts of my code:
var currentLocation : CLLocation?
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
if CLLocationManager.locationServicesEnabled() {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
// wait for currentLocation to be updated
animateMap(currentLocation!)
}
mapView.showsUserLocation = true
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
currentLocation = locations.last!
}
func animateMap(_ location: CLLocation) {
let region = MKCoordinateRegionMakeWithDistance(location.coordinate, 1000, 1000)
mapView.setRegion(region, animated: true)
}
You need to simply call that animateMap(currentLocation!) function in delegate method didUpdateLocations where you are initializing the currentLocation.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
currentLocation = locations.last!
animateMap(currentLocation!)
//Either Call `stop​Updating​Location()`
locationManager.stop​Updating​Location()
//Or you can create one boolean property with default value false and compare it inside this method
if !animatedFlag {
animateMap(currentLocation!)
animatedFlag = true
}
}
var animatedFlag = false
// MARK:- Location lattitude longtitude method Delegate Methods
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
if locationManager.location != nil
{
let locValue = (locationManager.location?.coordinate)!
lat = locValue.latitude
long = locValue.longitude
}
}
Call the animateMap function in didUpdateLocations delegate method, instead of in viewDidLoad. And, allow the map to center only the first time. You can you some bool variable for that.
var isLocationUpdated = false
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
currentLocation = locations.last!
if (!isLocationUpdated)
{
animateMap(currentLocation!)
isLocationUpdated = true
}
}

Getting My Location with google maps swift

I've got this code:
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
and this code:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation = locations.last
print(userLocation)
let camera = GMSCameraPosition.cameraWithLatitude(userLocation!.coordinate.latitude,
longitude: userLocation!.coordinate.longitude, zoom: 12.5)
self.mapView.camera = camera
self.mapView.myLocationEnabled = true
// self.mapView.settings.myLocationButton = true
locationManager.stopUpdatingLocation()
}
This was working earlier but now it seems like locationManager isn't even being called as the print statement isn't returning any information at all. There are no errors in the code and I can't seem to figure out why the function isn't being called. Can anyone spot anything obvious that I'm missing?
Thank you
I just implemented this and I'm going to say you what I've done
First, you create a locationManager variable
let locationManager: CLLocationManager = CLLocationManager()
You have to request permission in the viewDidLoad()
viewMap.delegate = self
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
Then, I created an extension and I implemented the delegate
extension MyView: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
//here you configure the locationManager
locationManager.startUpdatingLocation()
viewMap.isMyLocationEnabled = true
viewMap.settings.myLocationButton = true
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
}
I hope this help you, here works properly.

Resources