Home > Enterprise >  Swift MapKit Unable to show location with Pin
Swift MapKit Unable to show location with Pin

Time:11-17

I am new to swift . I am trying to show user location with Pin . I added the permission in Info Plist to allow the user access . I am using the storyboard and I tried to edit the schema also added the default location but it did not fixed the problem . I am using CLLocationManagerDelegate with MapKit.

Here is my code for view controller ..

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet var mapView: MKMapView!

    let manager  = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.delegate = self
        manager.requestWhenInUseAuthorization()
        manager.stopUpdatingLocation()
    }
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let location = locations.first {
            manager.stopUpdatingLocation()

            render(location)
        }
    }
    func  render(_ location: CLLocation) {

        let coordinate = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)

        let span  = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)

        let region  = MKCoordinateRegion(center: coordinate, span: span)

        mapView.setRegion(region, animated: true)

        let pin = MKPointAnnotation()
        pin.coordinate = coordinate
        mapView.addAnnotation(pin)

    }

}

Here is the screenshot of Info Plist Info Plist

Here is the screenshot shot when I run the app.. result

Here is the code warning .. Need to run into main thread

CodePudding user response:

Try this way: conform your ViewController class to CLLocationManagerDelegate and MKMapViewDelegate, declare your objects:

let mapView = MKMapView()
let manager = CLLocationManager()

in viewDidLoad present mapView and add constraints:

override func viewDidLoad() {
    super.viewDidLoad()
    
    mapView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(mapView)
    mapView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

}

in viewDidAppear call requestAlwaysAuthorization and requestWhenInUseAuthorization and map configuration

manager.requestAlwaysAuthorization()
manager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled() {
        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.startUpdatingLocation()
    }
    mapView.delegate = self
    mapView.mapType = .standard
    mapView.isZoomEnabled = true
    mapView.isScrollEnabled = true
    mapView.showsUserLocation = false // if you want to show default pin set to true

    if let coor = mapView.userLocation.location?.coordinate{
        mapView.setCenter(coor, animated: true)
    }

After that set didUpdateLocations

func locationManager(_ manager: CLLocationManager, didUpdateLocations
    locations: [CLLocation]) {
    
    guard let mylocation = manager.location else { return }
    
    let myCoordinates: CLLocationCoordinate2D = mylocation.coordinate

    mapView.mapType = MKMapType.standard

    let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
    let region = MKCoordinateRegion(center: myCoordinates, span: span)
    mapView.setRegion(region, animated: true)
    // comment pin object if showsUserLocation = true
    let pin = MKPointAnnotation()
    pin.coordinate = myCoordinates
    pin.title = "You are here"
    mapView.addAnnotation(pin)
}

my info.plist Privacy authorizations

enter image description here

The result, I set Tokyo on my simulator options scheme

enter image description here

enter image description here

intere code with your DispatchQueue request in comments below:

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {

let mapView = MKMapView()
let manager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    
    mapView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(mapView)
    mapView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    manager.requestAlwaysAuthorization()
    manager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled() {
        DispatchQueue.main.async {
            self.manager.delegate = self
            self.manager.desiredAccuracy = kCLLocationAccuracyBest
            self.manager.startUpdatingLocation()
            self.mapView.delegate = self
            self.mapView.mapType = .standard
            self.mapView.isZoomEnabled = true
            self.mapView.isScrollEnabled = true
            self.mapView.showsUserLocation = false // if you want to show default pin
        }
    }

    if let coor = mapView.userLocation.location?.coordinate {
        mapView.setCenter(coor, animated: true)
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations
    locations: [CLLocation]) {
    
    guard let mylocation = manager.location else { return }
    
    let myCoordinates: CLLocationCoordinate2D = mylocation.coordinate

    mapView.mapType = MKMapType.standard

    let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
    let region = MKCoordinateRegion(center: myCoordinates, span: span)
    mapView.setRegion(region, animated: true)
    
    let pin = MKPointAnnotation()
    pin.coordinate = myCoordinates
    pin.title = "You are here"
    mapView.addAnnotation(pin)
 }
}
  • Related