Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Current location in not working in Google Map

I have integrated google map in swift 3, when map screen appear than current location in not showing, i have added two keys in .plist file and also set CLLocationManager delegate and requestAlwaysAuthorization

class MapViewController: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate {

    @IBOutlet var mapView: GMSMapView!
    var marker: GMSMarker?


    override func viewDidLoad() {
         super.viewDidLoad()
         self.title = "MapVC"
         self.doSetupUI()
         self.searchLocation()
   }

   override func viewWillAppear(_ animated: Bool) {
         let locationManager : CLLocationManager = CLLocationManager()
         locationManager.delegate = self
         locationManager.requestAlwaysAuthorization()
   }



func doGoogleMapSetup(lat : Double , lng : Double) {
    let camera = GMSCameraPosition.camera(withLatitude: lat, longitude:lng, zoom:16)
    let mapView = GMSMapView.map(withFrame: .zero, camera:camera)
    mapView.isMyLocationEnabled = true

    let marker = GMSMarker()
    marker.position = CLLocationCoordinate2D(latitude: lat, longitude: lng)
    marker.snippet = ""
    marker.appearAnimation = kGMSMarkerAnimationPop
    marker.map = mapView

    let arrPoints : NSMutableArray = NSMutableArray()
    arrPoints.add(UserDefaults.standard.object(forKey: "addressPoints"))

    for i in 0..<arrPoints.count {
        let path : String = (arrPoints.object(at: i)as! NSMutableArray).object(at: 0) as! String
        let route : GMSPath = GMSPath.init(fromEncodedPath: path)!
        let polyLine : GMSPolyline = GMSPolyline.init(path: route)
        polyLine.strokeWidth = 2.0
        polyLine.strokeColor = UIColor.red
        polyLine.map = mapView
    }
}
like image 760
Dhanraj Avatar asked Nov 29 '22 00:11

Dhanraj


1 Answers

For showing current location we don't need any location manager in case of GoogleMaps. All we need is to add one of the keys or both in the .plist. So make sure the key is there. I have used NSLocationWhenInUseUsageDescription key.

<key>NSLocationWhenInUseUsageDescription</key>
    <string>Allow location</string>

enter image description here

Also make sure that you have called GMSServices provideAPIKey method and replaced with the API_KEY you generated in google developer console. Also all the relevant Google APIs as per requirement should be enabled.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
       // Override point for customization after application launch.
       GMSServices.provideAPIKey("YOUR_API_KEY")
       return true
    }

So, I am assuming you have done all the settings and things right in google developer console.

By just writing the below line in your controller where you have made the GoogleMap can show the location allow/disallow prompt and take the permission of the user.

mapView.isMyLocationEnabled = true

However this will not animate your map to your current location. But you can manually drag the map to check the current location and you will see a blue dot at your current location.

But now we also want to animate to the current location whenever we load that ViewController. Now the need for CLLocationManager arrives. So that in its didUpdateLocation delegate, we can fetch the current location and can just animate the graph to the current location.

So here is my complete controller.

import UIKit
import GoogleMaps

class ViewController: UIViewController,GMSMapViewDelegate,CLLocationManagerDelegate {
    @IBOutlet weak var mapView: GMSMapView!

    var locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        mapView.isMyLocationEnabled = true
        mapView.delegate = self

        //Location Manager code to fetch current location
        self.locationManager.delegate = self
        self.locationManager.startUpdatingLocation()
    }

    //Location Manager delegates
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        let location = locations.last

        let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude:(location?.coordinate.longitude)!, zoom:14)
        mapView.animate(to: camera)

        //Finally stop updating location otherwise it will come again and again in this delegate
        self.locationManager.stopUpdatingLocation()

    }
}

Another way of doing is not using the didUpdateLocation and not using the location manager is just by using the GMSMapViewDelegate delegate method mapViewDidFinishTileRendering

func mapViewDidFinishTileRendering(_ mapView: GMSMapView) {
    let location = mapView.myLocation
    let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude:(location?.coordinate.longitude)!, zoom:14)
    mapView.animate(to: camera)
}

It will be called everytime the map rendering is finished.
But this comes with a limitation, it will always bring you to the current location whenever you drag/pinch/zoom map as the rendering finish everytime you play with map. So, you can just implement some kind of bool variable logic here.

You can get your location by using

let yourCurrentLocation = mapView.myLocation

Make sure to do this on a device rather than simulator. If you are using simulator, you have to choose some custom location and then only you will be able to see the blue dot.

enter image description here

I already gave this type of answer. Check this Link. But that was in Swift 2.x. The one which I posted in this answer is in Swift 3.x

like image 101
Rajan Maheshwari Avatar answered Dec 05 '22 14:12

Rajan Maheshwari