'Blank Map with Mapbox and SwiftUI

I try to use Mapbox with SwiftUI.

I applied this answer https://stackoverflow.com/a/56551675/5653544 and also followed the mapbox tutorial.

So I have a MapView.swift view:

import SwiftUI
import Mapbox

extension MGLPointAnnotation {
    convenience init(title: String, coordinate: CLLocationCoordinate2D) {
        self.init()
        self.title = title
        self.coordinate = coordinate
    }
}

struct MapView: UIViewRepresentable {
    @Binding var annotations: [MGLPointAnnotation]

    private let mapView: MGLMapView = MGLMapView(frame: .zero, styleURL: MGLStyle.streetsStyleURL)

    // MARK: - Configuring UIViewRepresentable protocol

    func makeUIView(context: UIViewRepresentableContext<MapView>) -> MGLMapView {
        mapView.delegate = context.coordinator
        return mapView
    }

    func updateUIView(_ uiView: MGLMapView, context: UIViewRepresentableContext<MapView>) {
        updateAnnotations()
    }

    func makeCoordinator() -> MapView.Coordinator {
        Coordinator(self)
    }

    // MARK: - Configuring MGLMapView

    func styleURL(_ styleURL: URL) -> MapView {
        mapView.styleURL = styleURL
        return self
    }

    func centerCoordinate(_ centerCoordinate: CLLocationCoordinate2D) -> MapView {
        mapView.centerCoordinate = centerCoordinate
        return self
    }

    func zoomLevel(_ zoomLevel: Double) -> MapView {
        mapView.zoomLevel = zoomLevel
        return self
    }

    private func updateAnnotations() {
        if let currentAnnotations = mapView.annotations {
            mapView.removeAnnotations(currentAnnotations)
        }
        mapView.addAnnotations(annotations)
    }

    // MARK: - Implementing MGLMapViewDelegate

    final class Coordinator: NSObject, MGLMapViewDelegate {
        var control: MapView

        init(_ control: MapView) {
            self.control = control
        }

        func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {

            let coordinates = [
                CLLocationCoordinate2D(latitude: 37.791329, longitude: -122.396906),
                CLLocationCoordinate2D(latitude: 37.791591, longitude: -122.396566),
                CLLocationCoordinate2D(latitude: 37.791147, longitude: -122.396009),
                CLLocationCoordinate2D(latitude: 37.790883, longitude: -122.396349),
                CLLocationCoordinate2D(latitude: 37.791329, longitude: -122.396906),
            ]

            let buildingFeature = MGLPolygonFeature(coordinates: coordinates, count: 5)
            let shapeSource = MGLShapeSource(identifier: "buildingSource", features: [buildingFeature], options: nil)
            mapView.style?.addSource(shapeSource)

            let fillLayer = MGLFillStyleLayer(identifier: "buildingFillLayer", source: shapeSource)
            fillLayer.fillColor = NSExpression(forConstantValue: UIColor.blue)
            fillLayer.fillOpacity = NSExpression(forConstantValue: 0.5)

            mapView.style?.addLayer(fillLayer)

        }

        func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
            return nil
        }

        func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
            return true
        }

    }

}

and my ContentView.swift calling the MapView:

import SwiftUI
import Mapbox

struct ContentView: View {

    @State var annotations: [MGLPointAnnotation] = [
        MGLPointAnnotation(title: "Mapbox", coordinate: .init(latitude: 37.791434, longitude: -122.396267))
    ]

    var body: some View {
        MapView(annotations: $annotations).centerCoordinate(.init(latitude: 37.791293, longitude: -122.396324)).zoomLevel(16)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I also created a ~/.mapbox file with a mapbox token that I get with my mapbox account. But I have a blank map:

enter image description here

When I download and run the mapbox example, it works fine so I think it's not due to my Xcode version. Does anyone have a clue of why I can't load the map when I create the project by myself ?

Xcode version: 11.3

Mapbox version: 5.3.0



Solution 1:[1]

You need to set your MGLMapboxAccessToken in Info.plist.

Solution 2:[2]

I don't know if I should create a new ask for that but I had the same issue and I also had the MGLMapboxAccessToken in Info.plist (as proposed by @andrewcar).

In my case I was facing that issue when the app was sent to the background and then to the foreground.

I fixed it by adding a observer to the UIApplication.didBecomeActiveNotification notification and performing a unappreciable zoom change:

In viewDidLoad I added:

let becomeActiveNotification = NotificationCenter.default
becomeActiveNotification.addObserver(self, selector: #selector(didBecomeActiveNotification), name: UIApplication.didBecomeActiveNotification, object: nil)

Then I implemented didBecomeActiveNotification like that:

@objc func didBecomeActiveNotification() {
    self.mapView.setZoomLevel(14, animated: false)
    self.mapView.setZoomLevel(15, animated: false) // 15 is my desired zoom level
}

I hope it helps somebody, I was almost unable to find an answer for my issue.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 andrewcar
Solution 2 jjordan