Catch every moment when user change his location - ios

I am using Google Map SDK. I want to catch every moment when user changes his location, maybe from CLLocationManagerDelegate. Can anyone say which method can execute previous job?
I tried to use func locationManager( _ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) but it doesnot work well. When I run application, after 3-4 seconds this method call then If I change my location it doesnot do nothing.

Did you call startUpdatingLocation()?
Suppose that the below code is your CLLocationManager.
lazy var locationMgt: CLLocationManager = {
let manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
manager.distanceFilter = 1 // 1 meter
manager.activityType = .automotiveNavigation
manager.allowsBackgroundLocationUpdates = true
#if os(iOS)
manager.pausesLocationUpdatesAutomatically = false
#endif
manager.delegate = self
return manager
}()
Then ask for permission and start updating the location:
locationMgt.requestWhenInUseAuthorization()
// you can call startUpdatingLocation() inside this function or call it right after requestWhenInUseAuthorization()
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
locationMgt.startUpdatingLocation()
}
Then your delegate implementation:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let last = locations.last else { return }
// here user's last location is available.
}

Related

How to call "didUpdateLocation" method from viewDidLoad?

I am making a weather app which gets temperature info by sending current coordinates. So I am using CLLocationManager. I haven't make any HTTP request yet. I would like to see "Location Unavailable" on my screen but it is not working.
I am following a tutorial and wrote exactly same code but in tutorial it is working. In debug session, it doesn't jump to didFailwithError or didUpdateLocations methods.I added all necessary things in my
info.plist and my phone's location services are open. According to my research locationManager.startUpdatingLocation() should call automatically
these methods but when I run my app nothing appears on UI.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("you got the location")
}
//Write the didFailWithError method here:
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
cityLabel.text = "Location Unavaiable"
}
And
let locationManager = CLLocationManager ()
override func viewDidLoad() {
super.viewDidLoad()
//TODO:Set up the location manager here.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
You are updating location too soon, in fact before you get the permission from user.
After you ask for permission
locationManager.requestWhenInUseAuthorization()
Delegate method will call
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
}
Now its time to start updates. Guarding the status is a good idea since you don't want to start updating unless user permits it.
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
guard status == .authorizedWhenInUse else { return }
manager.startUpdatingLocation()
}
Now you'll get location updates
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
}

Google maps - Update User location

I am using Google maps SDK for iOS.
The isMyLocationEnabled is set to true.
Sometimes the use location updated to the right location. But sometimes the location is not updated.
I wanted to know if this option is using the original coordinates of the user? also, there is an option to update the user location? ) I am talking about the blue point.
May be this can help:
import Foundation
import CoreLocation
class Location: NSObject {
static let shared = Location()
var locationManager = CLLocationManager()
func locationManagerSetup() {
// Ask for Authorisation from the User.
locationManager.requestAlwaysAuthorization()
// If location services is enabled get the users location
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestLocation()
locationManager.startUpdatigLocation()
}
}
}
extension Location: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
// do something
manager.stopUpdatingLocation()
}
else {
manager.requestLocation()
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
manager.requestLocation()
}
// If we have been deined access give the user the option to change it
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if(status == CLAuthorizationStatus.denied) {
// do something
}
}
}

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