Using SwiftUI

A view with an MPIMapView can be created for use in SwiftUI by making use of an UIViewRepresentable. This allows an app with a SwiftUI based UI to make use of MPIMapView to display a map.

To allow calling methods of the MPIMapView, MPIMapView is instantiated as a state variable. The MPIMapViewDelegate and MPIMapClickDelegate interfaces are implemented within a Coordinator to communicate changes from the view to other parts of the app's SwiftUI interface.

Within the makeUIView, mapView.loadVenue is called, which accepts MPIOptions.Init containing the venue details and then renders the map. MPIMapViewDelegate and MPIMapClickDelegate are then added to mapView.

struct MapViewRepresentable: UIViewRepresentable {
var mapView = MPIMapView(frame: .zero)
class Coordinator: NSObject, MPIMapViewDelegate, MPIMapClickDelegate {
var parent: MapViewRepresentable
init(_ parent: MapViewRepresentable) {
self.parent = parent
}
func onClick(mapClickEvent: Mappedin.MPIMapClickEvent) {
print("The map was clicked")
}
func onDataLoaded(data: Mappedin.MPIData) {
print("Venue Data Loaded")
}
func onFirstMapLoaded() {
print("First Map Loaded")
}
func onMapChanged(map: Mappedin.MPIMap) {
print("Map Changed")
}
// Implement the rest of the MPIMapClickDelegate methods here.
func makeUIView(context: Context) -> MPIMapView {
mapView.loadVenue(
options: MPIOptions.Init(
clientId: "5eab30aa91b055001a68e996",
clientSecret: "RJyRXKcryCMy4erZqqCbuB1NbR66QTGNXVE0x3Pg6oCIlUR1",
venue: "mappedin-demo-mall"
))
mapView.delegate = context.coordinator
mapView.mapClickDelegate = context.coordinator
return mapView
}
func updateUIView(_ webView: MPIMapView, context: Context) {
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}

The MPIOptions.Init object contains a venue, clientId, clientSecret, and optional headers. To get started use the Mappedin Id and Secret that has access to demo venues. To start using your venues with the SDK you will need to contact a Mappedin representative to get your own unique Id and Secret.

The MapViewRepresentable is now ready to be added to a view. The code sample below shows adding it to a ContentView.

struct ContentView: View {
@State private var map = MapViewRepresentable()
var body: some View {
map
Button("Remove Labels") {
map.mapView.floatingLabelManager.removeAll()
}
}
}

Full Code Sample

Below is a complete code sample for using MPIMapView with a MPIMapViewDelegate and MPIMapClickDelegate in SwiftUI.

import SwiftUI
import Mappedin
struct MapViewRepresentable: UIViewRepresentable {
var mapView = MPIMapView(frame: .zero)
class Coordinator: NSObject, MPIMapViewDelegate, MPIMapClickDelegate {
var parent: MapViewRepresentable
init(_ parent: MapViewRepresentable) {
self.parent = parent
}
func onClick(mapClickEvent: Mappedin.MPIMapClickEvent) {
print("The map was clicked")
}
func onDataLoaded(data: Mappedin.MPIData) {
print("Venue Data Loaded")
}
func onFirstMapLoaded() {
print("First Map Loaded")
}
func onMapChanged(map: Mappedin.MPIMap) {
print("Map Changed")
}
func onPolygonClicked(polygon: Mappedin.MPIPolygon) {}
func onNothingClicked() {}
func onBlueDotPositionUpdate(update: Mappedin.MPIBlueDotPositionUpdate) {
print("Blue Dot Position Update")
}
func onBlueDotStateChange(stateChange: Mappedin.MPIBlueDotStateChange) {
print("Blue Dot State Change")
}
func onStateChanged(state: Mappedin.MPIState) {
print("State Changed")
}
func onCameraChanged(cameraChange: Mappedin.MPICameraTransform) {
print("Camera Changed")
}
}
func makeUIView(context: Context) -> MPIMapView {
mapView.loadVenue(
options: MPIOptions.Init(
clientId: "5eab30aa91b055001a68e996",
clientSecret: "RJyRXKcryCMy4erZqqCbuB1NbR66QTGNXVE0x3Pg6oCIlUR1",
venue: "mappedin-demo-mall"
))
mapView.delegate = context.coordinator
mapView.mapClickDelegate = context.coordinator
return mapView
}
func updateUIView(_ webView: MPIMapView, context: Context) {
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}
struct ContentView: View {
@State private var map = MapViewRepresentable()
var body: some View {
map
Button("Remove Labels") {
map.mapView.floatingLabelManager.removeAll()
}
}
}
#Preview {
ContentView()
}
Was this page helpful?