Skip to main content
This guide covers the complete setup process for integrating Open Mobile Maps into your iOS application using UIKit.

Requirements

  • iOS 14.0+
  • Xcode 13.0+
  • Swift 5.5+

Installation

Open Mobile Maps is available through Swift Package Manager.
1

Open package dependencies

In Xcode, select your project in the Project Navigator, then select your app target.
2

Add package

Go to the “Package Dependencies” tab and click the ”+” button.
3

Enter repository URL

Enter the repository URL:
https://github.com/openmobilemaps/maps-core
4

Select version

Choose “Up to Next Major Version” and enter 3.7.1 as the minimum version.
5

Add to target

Select your app target and click “Add Package”.
See Apple’s guide on Adding Package Dependencies to Your App for detailed instructions.

Set up MapView

The MCMapView is the main UI component for displaying maps in UIKit applications.
1

Import the framework

Import MapCore in your view controller:
import MapCore
2

Create a MapView

Create a MCMapView instance in your view controller:
MapViewController.swift
import UIKit
import MapCore

class MapViewController: UIViewController {
    lazy var mapView = MCMapView()
    
    override func loadView() {
        view = mapView
    }
}
3

Add a raster layer

Add a tiled raster layer in viewDidLoad():
override func viewDidLoad() {
    super.viewDidLoad()
    
    let rasterLayer = TiledRasterLayer(
        "osm",
        webMercatorUrlFormat: "https://tiles.sample.org/{z}/{x}/{y}.png"
    )
    mapView.add(layer: rasterLayer)
}
The webMercatorUrlFormat parameter expects a URL template with {z}, {x}, and {y} placeholders for zoom level and tile coordinates.
4

Set camera position

Position the camera to show a specific location:
mapView.camera.move(
    toCenterPositionZoom: MCCoord(
        lat: 46.962592372639634,
        lon: 8.378232525377973
    ),
    zoom: 1000000,
    animated: true
)

Complete example

Here’s a complete working example:
MapViewController.swift
import UIKit
import MapCore

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

Add vector tiles

Open Mobile Maps supports the Vector Tiles standard:
let vectorLayer = try! VectorLayer(
    "base-map",
    styleURL: "https://www.sample.org/base-map/style.json"
)
mapView.add(layer: vectorLayer)
Vector layer initialization can throw an error if the style URL is invalid. Handle errors appropriately in production code.

Multiple layers

You can combine multiple layers by adding them sequentially:
// Add base raster layer
let baseLayer = TiledRasterLayer(
    "base",
    webMercatorUrlFormat: "https://tiles.sample.org/{z}/{x}/{y}.png"
)
mapView.add(layer: baseLayer)

// Add vector overlay
let overlayLayer = try! VectorLayer(
    "overlay",
    styleURL: "https://www.sample.org/overlay/style.json"
)
mapView.add(layer: overlayLayer)

Custom map projection

To use a different coordinate system, initialize the map with a custom MapConfig:
let customMapView = MCMapView(
    mapConfig: .init(
        mapCoordinateSystem: MCCoordinateSystemFactory.getEpsg2056System()
    )
)
Layers can have a different projection than the map view itself. The SDK handles coordinate transformations automatically.

WMTS support

Parse WMTS capabilities to create layer configurations:
import MapCore

let resource = MCWmtsCapabilitiesResource.create(xml)!
let loader = MCTextureLoader()
let layer = resource.createLayer("identifier", tileLoader: loader)

mapView.add(layer: layer?.asLayerInterface())
This example uses the default MCTextureLoader implementation. You can provide a custom texture loader if needed.

Custom layer configuration

Create a custom layer configuration for different tile services:
import MapCore

class TiledLayerConfig: MCTiled2dMapLayerConfig {
    func getZoomInfo() -> MCTiled2dMapZoomInfo {
        MCTiled2dMapZoomInfo(
            zoomLevelScaleFactor: 0.65,
            numDrawPreviousLayers: 1,
            adaptScaleToScreen: true
        )
    }
    
    func getCoordinateSystemIdentifier() -> Int32 {
        MCCoordinateSystemIdentifiers.epsg3857()
    }
    
    func getBounds() -> MCRectCoord {
        let identifer = MCCoordinateSystemIdentifiers.epsg3857()
        let topLeft = MCCoord(
            systemIdentifier: identifer,
            x: -20037508.34,
            y: 20037508.34,
            z: 0.0
        )
        let bottomRight = MCCoord(
            systemIdentifier: identifer,
            x: 20037508.34,
            y: -20037508.34,
            z: 0.0
        )
        return MCRectCoord(
            topLeft: topLeft,
            bottomRight: bottomRight
        )
    }
    
    func getTileUrl(_ x: Int32, y: Int32, zoom: Int32) -> String {
        return "https://example.com/tiles/\(zoom)/\(x)/\(y).png"
    }
    
    func getLayerName() -> String {
        "OSM Layer"
    }
    
    func getZoomLevelInfos() -> [MCTiled2dMapZoomLevelInfo] {
        [
            .init(
                zoom: 559082264.029,
                tileWidthLayerSystemUnits: 40_075_016,
                numTilesX: 1,
                numTilesY: 1,
                numTilesT: 1,
                zoomLevelIdentifier: 0,
                bounds: getBounds()
            ),
            .init(
                zoom: 279541132.015,
                tileWidthLayerSystemUnits: 20_037_508,
                numTilesX: 2,
                numTilesY: 2,
                numTilesT: 1,
                zoomLevelIdentifier: 1,
                bounds: getBounds()
            ),
            // ... additional zoom levels
        ]
    }
}

Next steps

SwiftUI setup

Learn how to use Open Mobile Maps with SwiftUI

Add layers

Learn how to add and customize map layers

Build docs developers (and LLMs) love