Navvo
Guides

iOS SDK

Install and use the NavvoMaps Swift package — a NavvoMapView for UIKit/SwiftUI plus an async NavvoServices client for search, geocoding, places, routing, traffic and more.

iOS SDK

The official NavvoMaps Swift package gives you two things:

  • NavvoMapView — an embeddable, interactive Navvo basemap (UIKit view + a SwiftUI NavvoMap wrapper) pointed at Navvo's GET /tiles/style.
  • NavvoServices — an async/await actor for the Navvo Web Service (search, geocode, places, routing, traffic, matrix, isochrone, weather, EV, transit…).

Everything is Navvo-branded and only ever calls https://navvo.io/api/v1. Coordinates are uniformly LatLng(lat, lng).

Since 0.2.0 the package also includes CarPlay support (NavvoCarPlayController + NavvoCarPlaySceneDelegate, compile-guarded so it costs nothing without the entitlement), and it runs on iPhone and iPad alike — plus macOS via Designed for iPad.

Requires: iOS 13+ · Swift 5.9+ · CarPlay additionally needs Apple's com.apple.developer.carplay-maps entitlement.

Install

Download the package source from docs.navvo.io/sdks and add it to your project (or push it to your own SPM registry), then add NavvoMaps as a package dependency in Xcode.

Initialize

NavvoMaps.configure(apiKey: "nvvo_YOUR_KEY")
Provide your API key. Without a key the basemap renders with a "Navvo Map Developer (Provide Your API Key)" watermark on every tile. Basemap attribution is © Navvo.

Display a map

// SwiftUI
NavvoMap(style: .standard, camera: .init(target: LatLng(31.9539, 35.9106), zoom: 12))
    .markers([NavvoMarker(id: "a", position: LatLng(31.9539, 35.9106))])
    .onTap { latLng in /* … */ }

// UIKit
let mapView = NavvoMapView(frame: view.bounds)
mapView.setStyle(.dark)
mapView.moveCamera(CameraPosition(target: LatLng(31.9539, 35.9106), zoom: 12))

Use the services (no map required)

let svc = NavvoServices.shared // uses the key from NavvoMaps.configure

let result = try await svc.search("coffee in Abdoun", near: LatLng(31.95, 35.91), limit: 8)
let hits = try await svc.geocode("Rainbow Street, Amman")
let plan = try await svc.plan(RoutePlanRequest(
    locations: [PlanStop(LatLng(31.95, 35.91)), PlanStop(LatLng(31.99, 35.95))],
    costing: .auto
))

CarPlay

CarPlay support is built into the package (0.2.0+): a real NavvoMapView fills the car screen under a CPMapTemplate with zoom/pan buttons, plus a turn-by-turn skeleton (trip preview → CPNavigationSession → maneuver/ETA updates). Everything is wrapped in #if canImport(CarPlay) + @available(iOS 13.0, *), so the package builds unchanged for apps without CarPlay.

1. Entitlement — request CarPlay access from Apple, then add to your .entitlements:

<key>com.apple.developer.carplay-maps</key>
<true/>

2. Scene manifest — declare the CarPlay scene in Info.plist, pointing at the drop-in delegate (or your subclass of it):

<key>UIApplicationSceneManifest</key>
<dict>
    <key>UIApplicationSupportsMultipleScenes</key>
    <true/>
    <key>UISceneConfigurations</key>
    <dict>
        <key>CPTemplateApplicationSceneSessionRoleApplication</key>
        <array>
            <dict>
                <key>UISceneConfigurationName</key>
                <string>NavvoCarPlay</string>
                <key>UISceneDelegateClassName</key>
                <string>NavvoMaps.NavvoCarPlaySceneDelegate</string>
            </dict>
        </array>
    </dict>
</dict>

3. Controller usage — subclass the scene delegate to configure the map and drive navigation from your guidance logic:

final class CarPlaySceneDelegate: NavvoCarPlaySceneDelegate, NavvoCarPlayControllerDelegate {
    override func carPlayDidConnect(_ controller: NavvoCarPlayController) {
        controller.delegate = self
        controller.mapView?.setCamera(
            CameraPosition(target: LatLng(31.95, 35.91), zoom: 13), animated: false
        )
        let trip = controller.makeTrip(
            from: LatLng(31.95, 35.91), originName: "Start",
            to: LatLng(31.99, 35.86), destinationName: "Sweifieh"
        )
        controller.previewTrips([trip])
    }

    func carPlayController(
        _ controller: NavvoCarPlayController, didSelect trip: CPTrip, routeChoice: CPRouteChoice
    ) {
        controller.startNavigation(for: trip)
        controller.updateManeuver(instruction: "Turn right onto Rainbow Street",
                                  distanceRemainingMeters: 320, timeRemainingSeconds: 45)
        controller.updateTripEstimates(for: trip,
                                       distanceRemainingMeters: 5_400,
                                       timeRemainingSeconds: 11 * 60)
    }
}

Test in the Xcode CarPlay simulator (I/O → External Displays → CarPlay) — no entitlement needed there. NavvoMaps.configure(apiKey:) at app launch covers the CarPlay scene too.

iPad & macOS. The map view is fully adaptive on iPad (Split View, Slide Over, Stage Manager). On macOS, run the app via Designed for iPad on Apple silicon — zero changes; NavvoServices (pure Foundation) also compiles for Mac Catalyst as-is. For a native Windows/macOS/Linux desktop app, see the Desktop apps guide.

Errors

Every call throws NavvoError: .auth (401), .scope (403), .notFound (404), .validation (400/422), .rateLimit(retryAfter:) (429), .server (5xx), .network/.timeout. place(slug) returns nil for unknown slugs.

NavvoMapView renders via an embedded open-source map engine under the hood — you only ever interact with Navvo types and Navvo endpoints.
Copyright © 2026