Swift Quickstart
iOS / macOS native maps via MapLibre Native iOS.
Install (Swift Package Manager)
swift
// Package.swift dependencies
.package(url: "https://github.com/maplibre/maplibre-gl-native-distribution", from: "6.0.0")Add MapLibre product to your target.
Render a map
swift
import UIKit
import MapLibre
class MapViewController: UIViewController {
private var mapView: MLNMapView!
override func viewDidLoad() {
super.viewDidLoad()
let key = Bundle.main.object(forInfoDictionaryKey: "MFDPublicKey") as! String
let styleURL = URL(string:
"https://api.mapsfordevs.com/styles/standard.json?key=\(key)")!
mapView = MLNMapView(frame: view.bounds, styleURL: styleURL)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.setCenter(CLLocationCoordinate2D(latitude: -26.20, longitude: 28.04),
zoomLevel: 11, animated: false)
view.addSubview(mapView)
}
}Add bundle ID to your dashboard public-key allow-list.
Switch language
swift
import MapLibre
func setMapLanguage(_ map: MLNMapView, _ lang: String) {
let layers = ["place_label", "transportation_name", "poi_label"]
for id in layers {
guard let layer = map.style?.layer(withIdentifier: id) as? MLNSymbolStyleLayer else { continue }
layer.text = NSExpression(format:
"mgl_coalesce({CAST(name_\(lang), 'NSString'), CAST(name_latin, 'NSString'), CAST(name, 'NSString')})")
}
}(Actual key names: MapLibre converts name:de → name_de server-side in iOS bindings.)
Geocoding
swift
import Foundation
struct GeocodeItem: Decodable {
let lat: Double
let lng: Double
let label: String
let confidence: Double
let type: String
}
struct GeocodeResponse: Decodable {
let ok: Bool
let items: [GeocodeItem]?
let error: String?
}
enum MFDError: Error { case api(String) }
func geocode(query: String, country: String? = nil) async throws -> [GeocodeItem] {
let key = Bundle.main.object(forInfoDictionaryKey: "MFDPublicKey") as! String
var components = URLComponents(string: "https://api.mapsfordevs.com/geocode/forward")!
components.queryItems = [URLQueryItem(name: "q", value: query),
URLQueryItem(name: "limit", value: "5")]
if let country { components.queryItems?.append(URLQueryItem(name: "country", value: country)) }
var req = URLRequest(url: components.url!)
req.setValue("Bearer \(key)", forHTTPHeaderField: "Authorization")
let (data, _) = try await URLSession.shared.data(for: req)
let resp = try JSONDecoder().decode(GeocodeResponse.self, from: data)
guard resp.ok, let items = resp.items else { throw MFDError.api(resp.error ?? "unknown") }
return items
}SwiftUI wrapper
swift
import SwiftUI
import MapLibre
struct MapLibreView: UIViewRepresentable {
let styleURL: URL
let center: CLLocationCoordinate2D
let zoom: Double
func makeUIView(context: Context) -> MLNMapView {
let v = MLNMapView(frame: .zero, styleURL: styleURL)
v.setCenter(center, zoomLevel: zoom, animated: false)
return v
}
func updateUIView(_ v: MLNMapView, context: Context) {}
}