I have been looking at the google documentation to get the current location, but i am struggling to specify the location in the ViewDidLoad, as you can see i have set the Location fixed to Syndey Australia. In the google doc documentation when specifying the current location, they are using the "default location.coordinate" , i cannot access defaultLocation.coordinate in my code .
here is a link to the documenation : https://developers.google.com/maps/documentation/ios-sdk/current-place-tutorial
this is the code inside the viewDidLoad
GMSServices.provideAPIKey("AIzaSyARsPfNs54hrUAC4yKtHeu2jXfGjeA0b-E")
GMSPlacesClient.provideAPIKey("AIzaSyARsPfNs54hrUAC4yKtHeu2jXfGjeA0b-E ")
let camera = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 6.0)
mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
view = mapView
// creating the marker //
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: -33.86, longitude: 151.20)
marker.title = "Sydney"
marker.snippet = "Australia"
marker.map = mapView
This is my extenstion code
extension MapsViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location : CLLocation = locations.last!
print("Location:\(location)")
let camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude, longitude: location.coordinate.longitude, zoom: zoomLevel)
if mapView.isHidden {
mapView.isHidden = false
mapView.camera = camera
}
else {
mapView.animate(to: camera)
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted:
// display the map the default location
mapView.isHidden = false
case .denied :
print("User denied access to location")
mapView.isHidden = false
case .notDetermined :
print("Location status not deteremined")
case .authorizedAlways : fallthrough
case . authorizedWhenInUse :
print("Location status is OK")
}
}
I think you missed to add key NSLocationWhenInUseUsageDescription in your Info.plist file.
Add this key to the usage description.
It should then show an iOS system pop-up to allow location access.
I have read your question and checked you given link for Map Tutorial. I found some code missing in your viewDidLoad method:
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.distanceFilter = 50
locationManager.startUpdatingLocation()
locationManager.delegate = self
placesClient = GMSPlacesClient.shared()
Without assign delegate to the object of CLLocationManager like locationManager.delegate = self
I don't think even your extension would be called (CLLocationManagerDelegate).
Also
As per #Let's_Create answer info.plist shold have following keys to explain the user how the app uses this.
dataNSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription
Related
I realize there are lots of other pages that attempt to solve the challenge of getting user location using CLLocationManager() in ios swift but they don't work for me which is why I created this question. My code is below which I believe correctly implements the CLLocationManagerDelegate but the call to locationManager.startUpdatingLocation() never calls the locationManager function. This makes the Google Map simply open to a random position. I've simulated certain locations in the scheme and they work great like South Africa
example of Google Map with simulated location:
However, when I uncheck the simulation, the location is never found. Any advice or help would be appreciated. Not sure if this is a problem with my computer or code.
import UIKit
import GoogleMaps
class Map: UIViewController, CLLocationManagerDelegate {
var mapView: GMSMapView?
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.mapView = GMSMapView.map(withFrame: CGRect.zero, camera: GMSCameraPosition.camera(withLatitude: 40.7, longitude: -74.0, zoom: 4.0))
view = mapView
if (CLLocationManager.locationServicesEnabled()){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let center = CLLocationCoordinate2D(latitude: locations.last!.coordinate.latitude, longitude: locations.last!.coordinate.longitude)
let camera = GMSCameraPosition.camera(withLatitude: center.latitude, longitude: center.longitude, zoom: 4.0);
self.mapView?.camera = camera
self.mapView?.isMyLocationEnabled = true
let marker = GMSMarker(position: center)
print("Latitude :\(center.latitude)")
print("Longitude :\(center.longitude)")
marker.map = self.mapView
marker.title = "Current Location"
locationManager.stopUpdatingLocation()
}
}
I have been looking at the google documentation to get the current location, but i am struggling to specify the location in the ViewDidLoad, as you can see i have set the Location fixed to Syndey Australia. In the google doc documentation when specifying the current location, they are using the "default location.coordinate" , i cannot access defaultLocation.coordinate in my code .
here is a link to the documenation : https://developers.google.com/maps/documentation/ios-sdk/current-place-tutorial
this is the code inside the viewDidLoad
GMSServices.provideAPIKey("AIzaSyARsPfNs54hrUAC4yKtHeu2jXfGjeA0b-E")
GMSPlacesClient.provideAPIKey("AIzaSyARsPfNs54hrUAC4yKtHeu2jXfGjeA0b-E ")
let camera = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 6.0)
mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
view = mapView
// creating the marker //
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: -33.86, longitude: 151.20)
marker.title = "Sydney"
marker.snippet = "Australia"
marker.map = mapView
This is my extenstion code
extension MapsViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location : CLLocation = locations.last!
print("Location:\(location)")
let camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude, longitude: location.coordinate.longitude, zoom: zoomLevel)
if mapView.isHidden {
mapView.isHidden = false
mapView.camera = camera
}
else {
mapView.animate(to: camera)
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted:
// display the map the default location
mapView.isHidden = false
case .denied :
print("User denied access to location")
mapView.isHidden = false
case .notDetermined :
print("Location status not deteremined")
case .authorizedAlways : fallthrough
case . authorizedWhenInUse :
print("Location status is OK")
}
}
You have added wrong code in your method searchLocationPressed, Please update it as follow.
#IBAction func searchLocationPressed(_ sender: UIBarButtonItem) {
let autocomplete = GMSAutocompleteViewController()
autocomplete.delegate = self
self.present(autocomplete, animated: true, completion: nil)
}
Your mistake is you are presenting UISearchController instead of GMSAutocompleteViewController.
I am using Google Maps service for an app I am making using Xcode 9.2 and Swift 4. When I press a button I would like my current location to be marked on the map view with a marker above it. Instead, when tapping the button it takes me to the coordinates 0,0. What am I doing wrong? Thank you for all your help in advance.
//Location Manager
var userLocation = CLLocation()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
userLocation = locations.last!
let camera = GMSCameraPosition.camera(withLatitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude, zoom: 14);
self.googleMapsView.camera = camera
//Finally stop updating location otherwise it will come again and again in this delegate
self.locationManager.stopUpdatingLocation()
}
//Button Marker Function
#IBAction func markCurrentLocation(_ sender: UIButton) {
let center = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let camera = GMSCameraPosition.camera(withLatitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude, zoom: 14);
self.googleMapsView.camera = camera
self.googleMapsView.isMyLocationEnabled = true
let marker = GMSMarker(position: center)
print("Latitude :- \(userLocation.coordinate.latitude)")
print("Longitude :-\(userLocation.coordinate.longitude)")
marker.map = self.googleMapsView
marker.title = "Current Location"
googleMapsView.animate(to: camera)
//Finally stop updating location otherwise it will come again and again in this delegate
self.locationManager.stopUpdatingLocation()
}
It will return 0 because you created a new CLLocation() instance with nothing in it.
Get the current location from the locationManager(_:didUpdateLocations:) delegate.
Do it like:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
userLocation = locations.last
}
And remove let userLocation = CLLocation() from your markCurrentLocation(_:) method
Also be sure to add request in your info.plist
I am using Google Map on iOS, and I am getting the marker at my location but not getting camera position to my location. I have seen lots of tutorials but not getting any solution.
My code is :
mapView = GMSMapView()
locationManager = CLLocationManager()
// locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
placesClient = GMSPlacesClient.shared()
// GOOGLE MAPS SDK: COMPASS
mapView.settings.compassButton = true
// GOOGLE MAPS SDK: USER'S LOCATION
mapView.isMyLocationEnabled = true
mapView.settings.myLocationButton = true
mapView.animate(toBearing: 0)
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
if let location = locations.last
{
print("location\(String(describing: location))")
// mapView.clear()
let marker = GMSMarker(position: CLLocationCoordinate2D(latitude:location.coordinate.latitude, longitude: location.coordinate.longitude))
marker.map = mapview
mapView.camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude,
longitude: location.coordinate.longitude,
zoom: 50)
}
locationManager.stopUpdatingLocation()
}
Be sure to check GMSMapView.padding. It can differ from the rect of your GMSMapView, then camera will point to another position.
I'm trying to display the user's current location on a google map but in the case below, the map doesn't even get displayed. What should I change to fix this?
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//user location stuff
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Error" + error.description)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation = locations.last
let center = CLLocationCoordinate2D(latitude: userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude)
let camera = GMSCameraPosition.cameraWithLatitude(userLocation!.coordinate.latitude,
longitude: userLocation!.coordinate.longitude, zoom: 8)
let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
mapView.myLocationEnabled = true
self.view = mapView
let marker = GMSMarker()
marker.position = center
marker.title = "Current Location"
marker.snippet = "XXX"
marker.map = mapView
locationManager.stopUpdatingLocation()
}
You can try this bellow code its working fine
import UIKit
import GoogleMaps
import GooglePlaces
class SearchMapsViewController: UIViewController,
UINavigationBarDelegate, GMSAutocompleteFetcherDelegate,
LocateOnTheMap, UISearchBarDelegate, CLLocationManagerDelegate
{
#IBOutlet var googleMapsContainerView: UIView!
var searchResultController: SearchResultsController!
var resultsArray = [String]()
var googleMapsView:GMSMapView!
var gmsFetcher: GMSAutocompleteFetcher!
var locationManager = CLLocationManager()
override func viewDidAppear(animated: Bool) {
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
self.googleMapsView = GMSMapView (frame: self.googleMapsContainerView.frame)
self.googleMapsView.settings.compassButton = true
self.googleMapsView.myLocationEnabled = true
self.googleMapsView.settings.myLocationButton = true
self.view.addSubview(self.googleMapsView)
searchResultController = SearchResultsController()
searchResultController.delegate = self
gmsFetcher = GMSAutocompleteFetcher()
gmsFetcher.delegate = self
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print("Error" + error.description)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let userLocation = locations.last
let center = CLLocationCoordinate2D(latitude: userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude)
let camera = GMSCameraPosition.cameraWithLatitude(userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude, zoom: 15);
self.googleMapsView.camera = camera
self.googleMapsView.myLocationEnabled = true
let marker = GMSMarker(position: center)
print("Latitude :- \(userLocation!.coordinate.latitude)")
print("Longitude :-\(userLocation!.coordinate.longitude)")
marker.map = self.googleMapsView
marker.title = "Current Location"
locationManager.stopUpdatingLocation()
}
do requier setting on infoPlist and then try this
#IBOutlet weak var your "name of view which show map": GMSMapView!
override func viewDidLoad(){
super.viewDidLoad()
placesClient = GMSPlacesClient.shared()
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled(){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.distanceFilter = 500
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
mapView.settings.myLocationButton = true
mapView.settings.zoomGestures = true
mapView.animate(toViewingAngle: 45)
mapView.delegate = self }
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let newLocation = locations.last // find your device location
mapView.camera = GMSCameraPosition.camera(withTarget: newLocation!.coordinate, zoom: 14.0) // show your device location on map
mapView.settings.myLocationButton = true // show current location button
var lat = (newLocation?.coordinate.latitude)! // get current location latitude
var long = (newLocation?.coordinate.longitude)! //get current location longitude
}
The problem is that you are setting the mapView's frame to CGRectZero. This causes the map to have zero height and zero width, no wonder it does not show!
Try setting it to CGRectMake(0,0,200,200) for example, this will give you a map at the left top of the screen with a size of 200 x 200.
I have never used Swift before, so the syntax might be a little different for CGRectMake()
It seems that your creation of the map isn't in your viewDidLoad function. You may want to try moving that there and see what happens.
Add the appropriate properties into the info.plist.
You should put make sure you have the NS properties of locationalwaysusagedescription and wheninuseusagedescription in the information properties list. This allows for the permissions of the current location to be asked.
import UIKit
import GoogleMaps
import GooglePlaces
import CoreLocation
class MapsViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate {
var mapView = GMSMapView()
var locationManager = CLLocationManager()
let marker = GMSMarker()
override func viewDidLoad(){
super.viewDidLoad()
mapView.frame = self.view.bounds
self.view.addSubview(mapView)
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled(){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 10
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
mapView.settings.myLocationButton = true
mapView.settings.zoomGestures = true
mapView.animate(toViewingAngle: 45)
mapView.delegate = self
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let newLocation = locations.last // find your device location
mapView.camera = GMSCameraPosition.camera(withTarget: newLocation!.coordinate, zoom: 14.0) // show your device location on map
mapView.settings.myLocationButton = true // show current location button
let lat = (newLocation?.coordinate.latitude)! // get current location latitude
let long = (newLocation?.coordinate.longitude)! //get current location longitude
marker.position = CLLocationCoordinate2DMake(lat,long)
marker.map = mapView
print("Current Lat Long - " ,lat, long )
}
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
mapView.clear()
DispatchQueue.main.async {
let position = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
self.marker.position = position
self.marker.map = mapView
self.marker.icon = UIImage(named: "default_marker")
print("New Marker Lat Long - ",coordinate.latitude, coordinate.longitude)
}
}
}