LocationManager.startUpdatingLocation finishes too late , can't get current location - swift

I am trying to change the initial zoom location of my MapView.
I want the initialLocation to be (35,35) if myLocation == false and get the current Location if true. But startUpdatingLocation is finished after the initialLocation , so I cant get it and it crashes. If I use a breakpoint it works and gets the values.
if self.myLocation == false {
self.initialLocation = CLLocation(latitude: 35.00, longitude: 35.00) }
else {
locManager.delegate = self
locManager.desiredAccuracy = kCLLocationAccuracyBest
checkLocationAuthorizationStatus()
locManager.startUpdatingLocation()
self.initialLocation = CLLocation(latitude: locManager.location.coordinate.longitude, longitude: locManager.location.coordinate.longitude)
}
centerMapOnLocation(self.initialLocation)
}

You need to use the locationManager delegate: locationManager:didUpdateLocations to set the location.
Place your self.initialLocation= code in the delegate.
Then create another function that you can call to execute your centerMapOnLocation(self.initialLocation) code.

Related

Mapview camera zoom not getting set for the Current location

I want to set a proper zoom level for the User's current location using the Mapkit . I tried solutions from the stack but not working exactly for me . Can you guys please help me with the thing .
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.startUpdatingLocation()
mapView.showsUserLocation = true
for point in points {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: point["latitude"] as! Double, longitude: point["longitude"] as! Double)
mapView.addAnnotation(annotation)
}
** let region = MKCoordinateRegion(center: annotation.coordinate, latitudinalMeters: CLLocationDistance(exactly:9000)!, longitudinalMeters: CLLocationDistance(exactly: 9000)!)
mapView.setRegion(mapView.regionThatFits(region), animated: true) **
I tried this code but its not getting zoomed properly at users location .
Any help is appreciated .

How to set/update zoom level to GMSMapView in Swift?

Following code is how I got new marker position and update mapview.
if self.state.dropOff != nil {
let loc = response
let position = CLLocationCoordinate2D(latitude: loc.latitude!, longitude: loc.longitude!)
self.getPolylineRoute(from: self.state.pickUp!.coordinate, to: self.state.dropOff!.coordinate)
CATransaction.begin()
CATransaction.setAnimationDuration(1.0)
if self.acceptedCabMarker == nil {
self.acceptedCabMarker = GMSMarker(position: position)
}
self.acceptedCabMarker!.position = position
self.acceptedCabMarker!.isFlat = true
self.acceptedCabMarker!.icon = UIImage(named: markerIcon)
self.acceptedCabMarker!.setIconSize(scaledToSize: .init(width: 40, height: 40))
self.acceptedCabMarker!.appearAnimation = .pop
self.acceptedCabMarker!.rotation = CLLocationDegrees(loc.bearing ?? 0)
CATransaction.commit()
DispatchQueue.main.async {
self.acceptedCabMarker!.map = self.mapView
}
}
Problem is everytime this code is executed, mapview zoom level became to its original state. Which mean user can't zoom the map for long.
I tried to save the zoom using method.
extension SomeHomeViewController: GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
print("Camera Zoom: \(position.zoom)")
currentPosition = position
}
}
But I can't reuse currentPosition because
self.mapView?.camera.zoom = currentPosition?.zoom
is not allowed.
You can simply set the zoom on GMSMapView in this way
let camera = GMSCameraPosition.camera(withLatitude: loc.latitude, longitude: loc.longitude, zoom: 10.0)
self.mapView.camera = camera
You need to use
- (void)animateToZoom:(float)zoom;
method which is defined in GMSMapView (Animation) Category. For more info you can refer this link.

Obtaining user location not functioning in Xcode

Good evening, I am trying to allow users to locate themselves on a map. When I run the app and access my google maps view, I get the error message "this app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an “NSLocationWhenInUseUsageDescription” key with a string value explaining to the user how the app uses this data" and the map is set a default state.
I have put
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs your current location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs your current location</string>
in my info.plist, but it tells me that I need to put in NSLocationWhenInUseUsageDescription in order to access location. I already have put it in and it still won't show the user location! Am I leaving something out or is this a bug? it worked fine for me before I updated to the newest version of Xcode.
My code that enables google maps is as follows,
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
locationManager.delegate = self
locationManager.stopUpdatingLocation()
let location = locations.last
let lat = (location?.coordinate.latitude)!
let long = (location?.coordinate.longitude)!
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: long, zoom: 17.0)
self.myMapView.animate(to: camera)
showPartyMarkers(lat: lat, long: long)
}
func initGoogleMaps() {
let camera = GMSCameraPosition.camera(withLatitude: 40.014281, longitude: -83.030914, zoom: 17.0)
self.myMapView.camera = camera
self.myMapView.delegate = self
self.myMapView.isMyLocationEnabled = true
}
func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) {
let lat = place.coordinate.latitude
let long = place.coordinate.longitude
showPartyMarkers(lat: lat, long: long)
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: long, zoom: 17.0)
myMapView.camera = camera
txtFieldSearch.text=place.formattedAddress
Add new records in your new InfoPlist.strings file.
<key>NSLocationAlwaysUsageDescription</key>
<string>app need your location for finding a place</string>
add lines in viewdidload
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
delete your app from simulator and run again.
Add below keys in plist.
Privacy - Location Always and When In Use Usage Description
Privacy - Location When In Use Usage Description
EDIT
I am not seeing Initialisation for locationManager.
Use below code to initialise:
/// CLLocationManager object
var locationManager: CLLocationManager = {
let manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyBest
return manager
}()
After Init start updating location, for that add below lines in viewDidload
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
I found the answer after reposting the question. If anyone is having this issue as well, what you want to do is click on your projects target build settings, click on info (Left of build settings) and you want to make sure the Custom iOS Target Properties have the same info as your regular p-list. If it does not, simply click the plus sign, and add them in. This should fix the problem because it has with mine. I hope you all find this useful.

how to keep the current location dot on the centre of the map when moving, google map, swift

In my project I am using google map. I am enabling the current location dot like this:
self.mapView?.isMyLocationEnabled = true
After that I am getting the current location latitude and longitude like this:
guard let currentLat = self.mapView?.myLocation?.coordinate.latitude,
let currentLan = self.mapView?.myLocation?.coordinate.longitude else {
showMessageFail(title: "Fail", myMessage: "Could not determine your current location")
return
}
And then focusing the camera on current location like this:
let currentPosition = CLLocationCoordinate2D(latitude: currentLat, longitude: currentLan)
self.mapView?.animate(toLocation: self.currentPosition)
Everything is perfectly fine, now it shows the current location dot (the blue dot on google map) on the centre of the map. Now when current location changed, say I am in a car the current location dot moves, at some point it moves out of the bounds of the map. How can I always keep the current location dot on the centre of the map and move the map not the dot. Any help would be really appreciated.
currLocation = manager.location!
let locationOfDevice: CLLocation = currLocation // this determines the location of the device using the users location
let deviceCoordinate: CLLocationCoordinate2D = locationOfDevice.coordinate // determines the coordinates of the device using the location device variabel which has in it the user location.
let span = MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1) // this determines the span in which its determined that 1 degree is 69 miles.
let region = MKCoordinateRegion(center: deviceCoordinate, span: span) // set the center equal to the device coordinates and the span equal to the span variable we have created this will give you the region.
mapView.setRegion(region, animated: true);
CLLocation *newMyLocation = [[CLLocation alloc] initWithLatitude:_locationManager.location.coordinate.latitude longitude:_locationManager.location.coordinate.longitude];
_cmarker.position = newMyLocation.coordinate;
CGPoint point1 =[_mapkitView.projection pointForCoordinate:newMyLocation.coordinate];
point1.y = -400;
GMSCameraUpdate *cameraUpdate = [GMSCameraUpdate setTarget:[_mapkitView.projection coordinateForPoint:point1]];
[_mapkitView animateWithCameraUpdate:cameraUpdate];
_cmarker.map = self.mapkitView;
//[_mapkitView setCenterCoordinate:newMyLocation.coordinate zoomLevel:_mapkitView.zoomLevel animated:YES];
[_mapkitView animateToLocation:CLLocationCoordinate2DMake(newMyLocation.coordinate.latitude, newMyLocation.coordinate.longitude)];
[_mapkitView animateToZoom:_mapkitView.camera.zoom]; // animate to that zoom level

Printing user location distance in meters from marker every X seconds with Timer, in Swift 3

Disclaimer: very beginner level coder here, so excuse any "obvious" mistakes.
I am trying to build an app that shows to user how close they are to a marker.
I have a GoogleMaps map view and I want to refresh user location continuously (every say 3 seconds). calculate and print its linear distance (in meters) from the marker, and set that to my left navigation item button.
I tried doing this through GoogleMaps to no avail. So tried with CLLocation and CoreLocation.
Problem is, I get first value in meters (15m), second value (9m) 3 seconds later, then every other 3 second iteration of my timer only gives 9m forever, no matter if I move around (and my googlemaps view does update successfully the blue user position dot as I move around, laptop and linked ipad in hand).
What I am doing is have my timer fire off "findDistance" function every 3 seconds. The "findDistance" function runs locationmanager (which sets globalUserLocation to current one - if I am not doing something wrong), calculates distance and sets it to GlobalDistance, then updates the left navigation button item to that new distance.
But it seems like the user location is only updated twice (instead of every 3 seconds, forever).
What am I doing wrong? Any help would be greatly appreciated
I have added all the plist requirements, and here is my code:
import UIKit
import GoogleMaps
import CoreLocation
import MapKit
class googleMaps: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
let locationmanager = CLLocationManager()
var globalDistance: CLLocationDistance = 0
var mapView: GMSMapView? = nil
var globalUserLocation = CLLocation(latitude: 40.085260, longitude: 22.601468)
override func viewDidLoad() {
super.viewDidLoad()
let timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(googleMaps.findDistance), userInfo: nil, repeats: true)
self.locationmanager.delegate = self
self.locationmanager.desiredAccuracy = kCLLocationAccuracyBest
self.locationmanager.startUpdatingLocation()
timer.fire()
GMSServices.provideAPIKey("**mykeyhere**")
let camera = GMSCameraPosition.camera(withLatitude: 40.085260 , longitude: 22.601468, zoom: 40)
mapView = GMSMapView.map(withFrame: CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: 200, height: 500)), camera: camera)
mapView?.isMyLocationEnabled = true
view = mapView
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "\(globalDistance)", style: UIBarButtonItemStyle.plain, target: self, action: #selector(googleMaps.next as (googleMaps) -> () -> ()))
mapView?.mapType = kGMSTypeNormal
self.mapView?.settings.myLocationButton = true
self.mapView?.settings.compassButton = true
}
func locationmanager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
globalUserLocation = locations.last!
}
func findDistance(){
locationmanager
let currentLat = locationmanager.location!.coordinate.latitude
let currentLong = locationmanager.location!.coordinate.longitude
globalUserLocation = CLLocation(latitude: currentLat, longitude: currentLong)
let myMarker = CLLocation(latitude: 40.085260, longitude: 22.601468)
if globalUserLocation != nil {
let distance = globalUserLocation.distance(from: myMarker)
print(distance)
globalDistance = distance
navigationItem.leftBarButtonItem?.title = "\(globalDistance)"
}
}