iOS MKMapView OpenStreetMap Tile-Overlay


Example

In some cases, you might not want to use the default maps, Apple provides.

You can add an overlay to your mapView that contains custom tiles for example from OpenStreetMap.

Let's assume, self.mapView is your MKMapView that you have already added to your ViewController.

At first, your ViewController needs to conform to the protocol MKMapViewDelegate.

class MyViewController: UIViewController, MKMapViewDelegate

Then you have to set the ViewController as delegate of mapView

mapView.delegate = self

Next, you configure the overlay for the map. You'll need an URL-template for this. The URL should be similar to this on all tile-servers and even if you would store the map-data offline: http://tile.openstreetmap.org/{z}/{x}/{y}.png

let urlTeplate = "http://tile.openstreetmap.org/{z}/{x}/{y}.png"
let overlay = MKTileOverlay(urlTemplate: urlTeplate)
overlay.canReplaceMapContent = true

After you configured the overlay, you must add it to your mapView.

mapView.add(overlay, level: .aboveLabels)

To use custom maps, it is recommended to use .aboveLabels for level. Otherwise, the default labels would be visible on your custom map. If you want to see the default labels, you can choose .aboveRoads here.

If you would run your project now, you would recognize, that your map would still show the default map:

first run. still default map visible

That's because we haven't told the mapView yet, how to render the overlay. This is the reason, why you had to set the delegate before. Now you can add func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer to your view controller:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay is MKTileOverlay {
        let renderer = MKTileOverlayRenderer(overlay: overlay)
        return renderer
    } else {
        return MKTileOverlayRenderer()
    }
}

This will return the correct MKOverlayRenderer to your mapView. If you run your project now, you should see a map like this:

working OSM overlay

If you want to display another map, you just have to change the URL-template. There is a list of tile-servers in the OSM Wiki.