Jayden Patterson
Jayden Patterson

Reputation: 13

annotations not appearing on MapKit

Has anyone experienced opening a map in your app and although it shows the area you are in it doesn't show the blue dot. Also I'm using localSearch to find supermarkets in my app. When you originally open the map it shows nothing. When you close and open the app again the annotations magically appear. Am I missing something really obvious?

Also I am receiving these errors in the console:

Wrapped around the polygon without finishing... :-(

List has 10 nodes:
    7 8 9 10 4 3 0 1 2 6 
2022-02-20 17:55:28.093927+0900 GoferList[15460:5478085] [VKDefault] Building failed to triangulate!
2022-02-20 17:55:28.265877+0900 GoferList[15460:5478094] [Font] Failed to parse font key token: hiraginosans-w6

Here is the view controller I'm using:

import CoreLocation
import MapKit
import UIKit

class MapViewController: UIViewController {
    static func createViewController() -> MapViewController? {
        UIStoryboard(name: "Main", bundle: Bundle.main)
            .instantiateInitialViewController() as? MapViewController
    }

    @IBOutlet private var mapView: MKMapView!
    private let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        configureLocationManager()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        locationManager.startUpdatingLocation()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        locationManager.stopUpdatingLocation()
    }
}

// MARK: - Location Manager

extension MapViewController: CLLocationManagerDelegate {
    func configureLocationManager() {
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = kCLDistanceFilterNone
    }

    func locationManager(
        _ mgr: CLLocationManager,
        didUpdateLocations locations: [CLLocation]
    ) {
        guard let location = locations.first else {
            return
        }
        let region = MKCoordinateRegion(
            center: location.coordinate,
            latitudinalMeters: 1000,
            longitudinalMeters: 1000
        )
        mapView.setRegion(region, animated: false)
        findPOIPlaces(query: "supermarket", region: region)
        mgr.stopUpdatingLocation()
    }
}

// MARK: - MapViewDelegate

extension MapViewController: MKMapViewDelegate {
    func findPOIPlaces(query: String, region: MKCoordinateRegion) {
        let searchRequest = MKLocalSearch.Request()
        searchRequest.naturalLanguageQuery = query
        searchRequest.resultTypes = .pointOfInterest
        searchRequest.region = region

        let search = MKLocalSearch(request: searchRequest)
        search.start { [weak self] res, error in
            guard let res = res,
                  let self = self,
                  error == nil
            else {
                print("\(String(describing: error))")
                return
            }
            for item in res.mapItems {
                let annotation = SuperMarketAnnotation(item: item)
                self.mapView.addAnnotation(annotation)
            }
        }
    }

    func mapView(
        _ mapView: MKMapView,
        viewFor annotation: MKAnnotation
    ) -> MKAnnotationView? {
        guard annotation is SuperMarketAnnotation else {
            return nil
        }
        if let view = mapView.dequeueReusableAnnotationView(
            withIdentifier: SuperMarketAnnotationView.reuseID)
        {
            return view
        }
        let annotationView = SuperMarketAnnotationView(annotation: annotation)
        annotationView.delegate = self
        return annotationView
    }
}

// MARK: - SuperMarketAnnotationViewDelegate

extension MapViewController: SuperMarketAnnotationViewDelegate {
    func onTapPin(annotation: SuperMarketAnnotation) {
        mapView.setCenter(annotation.coordinate, animated: true)
    }

    func onTapInfo(annotation: SuperMarketAnnotation) {
        if let url = annotation.webURL {
            // if place has an web site
            if let vc = WebViewController.createViewController() {
                vc.url = url
                vc.name = annotation.title
                present(vc, animated: true, completion: nil)
            }
        } else if let url = annotation.externalURL {
            UIApplication.shared.open(
                url, options: [:],
                completionHandler: nil
            )
        }
    }
}

Can anyone help? Thank you.

Upvotes: 1

Views: 1126

Answers (1)

Rob
Rob

Reputation: 437542

A few observations:

  • Regarding not seeing the blue dot, the question is whether you set showsUserLocation (either programmatically or in the NIB/storyboard).

  • Regarding annotations not showing up, you need to narrow down the problem. I would temporarily remove the mapView(_:viewFor:) and see whether you see annotations at that point.

    • If they do, then the problem is either in mapView(_:viewFor:) (see below) or your custom annotation view subclass.
    • If they do not appear, then the problem is either in your logic of how/when you added annotation or in your custom annotation class.
    • With mapView(_:viewFor:) removed, you could then try adding a MKPointAnnotation, rather than your SuperMarketAnnotation. That will help you figure out whether the problem is in your annotation class or the the logic about when and where you add annotations.
  • FWIW, the mapView(_:viewFor:) has a little bug (which may or may not be related). If you successfully dequeue an existing annotation view, you just return it and never update its annotation property. You must update the annotation of any dequeued annotation view or else it will point to the old annotation (and, specifically, its old coordinate).

    if let view = mapView.dequeueReusableAnnotationView(withIdentifier: SuperMarketAnnotationView.reuseID) {
        view.annotation = annotation // make sure you update the annotation for dequeued annotation view
        return view
    }
    

Upvotes: 1

Related Questions