Skip to main content

Overview

Open Mobile Maps provides two approaches for displaying maps in iOS applications: MCMapView for UIKit and MapView for SwiftUI. Both provide a view that can be filled with layers.

SwiftUI MapView

The SwiftUI MapView requires iOS 17.0 or later.
For SwiftUI applications, use the declarative MapView interface.

Basic Setup

import MapCore
import SwiftUI

struct ContentView: View {
    @State private var camera = MapView.Camera(
        latitude: 46.962592372639634,
        longitude: 8.378232525377973,
        zoom: 1000000
    )
    @State private var layers: [any Layer] = []
    
    var body: some View {
        MapView(
            camera: $camera,
            layers: layers
        )
        .onAppear {
            setupLayers()
        }
    }
    
    private func setupLayers() {
        layers = [
            TiledRasterLayer("osm", webMercatorUrlFormat: "https://tiles.sample.org/{z}/{x}/{y}.png")
        ]
    }
}

Camera Binding

The camera binding allows you to observe and control the map’s camera position. The camera updates automatically as users interact with the map, and you can programmatically change the camera position by updating the binding.
camera
Binding<MapView.Camera>
required
Two-way binding for camera position control
latitude
Double
Latitude coordinate of the camera center
longitude
Double
Longitude coordinate of the camera center
zoom
Double
Zoom level of the camera

Multiple Layers

You can combine multiple layers by passing them in the layers array:
struct ContentView: View {
    @State private var camera = MapView.Camera(
        latitude: 46.962592372639634,
        longitude: 8.378232525377973,
        zoom: 1000000
    )
    @State private var layers: [any Layer] = []
    
    var body: some View {
        MapView(
            camera: $camera,
            layers: layers
        )
        .onAppear {
            setupLayers()
        }
    }
    
    private func setupLayers() {
        layers = [
            TiledRasterLayer("base", webMercatorUrlFormat: "https://tiles.sample.org/{z}/{x}/{y}.png"),
            try! VectorLayer("overlay", styleURL: "https://www.sample.org/overlay/style.json")
        ]
    }
}

3D Mode

Enable 3D rendering for supported layers:
MapView(
    camera: $camera,
    layers: layers,
    is3D: true
)
is3D
Bool
default:"false"
Enable 3D map rendering

Custom Map Projection

To render the map using a different coordinate system, initialize the map view with a Map Config:
struct ContentView: View {
    @State private var camera = MapView.Camera(
        latitude: 46.962592372639634,
        longitude: 8.378232525377973,
        zoom: 1000000
    )
    @State private var layers: [any Layer] = []
    
    var body: some View {
        MapView(
            camera: $camera,
            mapConfig: .init(mapCoordinateSystem: MCCoordinateSystemFactory.getEpsg2056System()),
            layers: layers
        )
        .onAppear {
            setupLayers()
        }
    }
    
    private func setupLayers() {
        layers = [
            TiledRasterLayer("osm", webMercatorUrlFormat: "https://tiles.sample.org/{z}/{x}/{y}.png")
        ]
    }
}
mapConfig
MCMapConfig
Configuration for map coordinate system and rendering settings

UIKit MCMapView

For UIKit applications, use MCMapView directly:
import MapCore

class MapViewController: UIViewController {
    lazy var mapView = MCMapView()
    override func loadView() { view = mapView }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        mapView.add(layer: TiledRasterLayer("osm", webMercatorUrlFormat: "https://tiles.sample.org/{z}/{x}/{y}.png"))
        
        mapView.camera.move(toCenterPositionZoom: MCCoord(lat: 46.962592372639634, lon: 8.378232525377973), zoom: 1000000, animated: true)
    }
}

Adding Layers

mapView.add(layer: TiledRasterLayer("osm", webMercatorUrlFormat: "https://tiles.sample.org/{z}/{x}/{y}.png"))

Custom Map Projection

MCMapView(mapConfig: .init(mapCoordinateSystem: MCCoordinateSystemFactory.getEpsg2056System()))

WMTS Capabilities

Open Mobile Maps supports the WMTS standard and can parse Capability XML files to generate raster layer configurations.

SwiftUI

struct ContentView: View {
    @State private var camera = MapView.Camera(
        latitude: 46.962592372639634,
        longitude: 8.378232525377973,
        zoom: 1000000
    )
    @State private var layers: [any Layer] = []
    
    var body: some View {
        MapView(
            camera: $camera,
            layers: layers
        )
        .onAppear {
            setupWMTSLayer()
        }
    }
    
    private func setupWMTSLayer() {
        guard let resource = MCWmtsCapabilitiesResource.create(xml),
              let wmtsLayer = resource.createLayer("identifier", tileLoader: MCTextureLoader()) else {
            return
        }
        layers = [wmtsLayer]
    }
}

UIKit

let resource = MCWmtsCapabilitiesResource.create(xml)!
let layer = resource.createLayer("identifier", tileLoader: loader)
mapView.add(layer: layer?.asLayerInterface())
xml
String
required
WMTS Capabilities XML content
identifier
String
required
Layer identifier from the WMTS capabilities
tileLoader
MCTextureLoader
required
Texture loader for tile rendering

Vector Tiles

Open Mobile Maps supports most of the Vector tiles standard. Add a vector layer by referencing the style URL:

SwiftUI

private func setupLayers() {
    layers = [
        try! VectorLayer("base-map", styleURL: "https://www.sample.org/base-map/style.json")
    ]
}

UIKit

mapView.add(layer: try! VectorLayer("base-map", styleURL: "https://www.sample.org/base-map/style.json"))

Build docs developers (and LLMs) love