Skip to content
Developers Docs

Mapsted Maps - Mobile Docs

Migration Guide to SDK v6.2.0+

This guide assists developers in migrating from Mapsted SDK v6.1.12 to v6.2.0+.

1. iOS Migration

We have restructured the routing and navigation features in the mobile SDK as outlined below.

2. Routing and Navigation Changes

2.1 Overview

In SDK v6.2.0, we have improved and enhanced the routing and navigation module. The new routing and navigation module simplifies route handling and adds flexibility to listen for routing and navigation callbacks from classes other than those that request routes and start navigation.

2.2 Key Changes

  • New route structure: Routes now provide more route paths for every route request
  • API modifications: Minor modifications to public-facing APIs for route requests
  • Updated callbacks: Modified RoutingRequestCallback and introduced NavigationCallback, which replaces RoutingStatusCallback

2.3 Terminology & Structure Changes

2.3.1 Route Request

Concept Old New Explanation
Route Request MNRouteRequest MNRouteRequest
Routing Options MNRouteOptions MNRoutingOptions The name of the object has changed. Moreover, there is an additional option for Ramps.
Impacts MNRoutingConstraints The routing constraints object will be used for alerts details, access level details, etc. to the route request.
Start Point id<Searchable> id<Searchable>
Destinations NSArray<Searchable> * NSArray<Searchable> *

2.3.2 Routing Response

Concept Old New
Route Response MNRouteResponse MNRouteResponse
Routes Single list of MNRoute List of MNRoute, each having multiple MNRoutePath
Route Segments MNRouteSegment MNRoutePathSegment
Navigation Nodes MNRouteNode MNRoutePointInstruction
Distance Time MNRouteDistanceTime MNDistanceTime
Error error message and error code MNRouteError

2.3.3 Routing & Navigation Callback

Concept Old New
Routing Callback RoutingRequestCallback RoutingRequestCallback
Navigation Callback RoutingStatusCallback NavigationCallback

2.3.4 Routing Callback

Event Old (RoutingRequestCallback) New (RoutingRequestCallback) Explanation
Success func onSuccess(routeResponse: MNRouteResponse) func onSuccess(routeResponse: MNRouteResponse)
Failure func onError(errorCode: Int, errorMessage: String, alertIds: [String]) func onError(routeResponse: MNRouteResponse) Here routeResponse object has routeError object which has details of the error.

2.3.5 Navigation Callback

Event Old (RoutingStatusCallback) New (NavigationCallback) Explanation
Route Status func onRoutingStatus(isRoutingModeOn: Bool, latestRouteResponse: MNRouteResponse) func onNavigationInitSuccess(state: MNNavigationState) & func onNavigationInitFailure(error: MNNavigationError)
Route Segment Reached func onRouteSegmentReached(currentRouteSegment: MNRouteSegment, visitedRouteSegments: [MNRouteSegment], upcomingRouteSegments: [MNRouteSegment]) func onRouteSegmentReached(currentSegment: MNRoutePathSegment, visitedSegments: [MNRoutePathSegment], upcomingSegments: [MNRoutePathSegment])
User Progress func onUserProgressAlongRoute(routeUserProgress: MNRouteUserProgress) func onUserProgressAlongRoute(state: MNNavigationState)
Instruction Update func onRouteInstructionReceived(routeNode: MNRouteNode, nextRouteNode: MNRouteNode?) func onRouteInstruction(currentInstruction: MNRoutePointInstruction, nextInstruction: MNRoutePointInstruction, afterNextInstruction: MNRoutePointInstruction) In the new version, nextInstruction is to be displayed and distance and time are to be taken from the currentInstruction as shown in the code snippet in section 2.4.6.
Route Recalculation func onRouteRecalculation(newRouteResponse: MNRouteResponse) func onRouteRecalculation(state: MNNavigationState, newRoute: MNRoute, routePathType: MNRoutePathType)
Destination Reached func onDestinationReached(waypoint: MapstedWaypoint) func onDestinationReached(destination: MapstedWaypoint)

2.4 Migration Steps

2.4.1 Add and Remove Listeners for Routing & Navigation Callbacks

In previous versions, there was no way to add or remove routing and navigation listeners on screens other than those where navigation is initiated.

In SDK v6.2.0+, this has been simplified to:

    // Add routing request listener
    CoreApi.RoutingManager.addRoutingCallbackListener(listener: self)

    // Add navigation listener
    CoreApi.RoutingManager.addNavigationCallbackListener(listener: self)

    // Remove routing request listener
    CoreApi.RoutingManager.removeRoutingCallbackListener(listener: self)

    // Remove navigation listener
    CoreApi.RoutingManager.removeNavigationCallbackListener(listener: self)

2. Make Route Request

In previous versions, route requests were set up with the following calls:

//Builds and sends a route request with given start point, destinations, and route preferences.
func makeRouteRequest(start: ISearchable?, fromCurrentLocation: Bool, destinations: [ISearchable]) {

    let start = start as? MNSearchEntity
    let pois = destinations.compactMap({$0 as? MNSearchEntity})

    //Create Route Options
    let routeOptions = MNRouteOptions(false, escalators: true, elevators: true, current: fromCurrentLocation, optimized: true)

    //Build a route request
    let routeRequest = MNRouteRequest(routeOptions: routeOptions, destinations:pois, startEntity: fromCurrentLocation ? nil : start)

    DispatchQueue.global(qos: .userInteractive).async {
        CoreApi.RoutingManager.requestRoute(request: routeRequest, routingRequestCallback: self)
    }
}

In SDK v6.2.0+, this has been simplified to:

//Builds and sends a route request with given start point, destinations, and route preferences.
func makeRouteRequest(start: ISearchable?, fromCurrentLocation: Bool, destinations: [ISearchable]) {
    let start = start as? MNSearchEntity
    let pois = destinations.compactMap({$0 as? MNSearchEntity})

    //Create Route Options
    let routingOptions = MNRoutingOptionsBuilder().setIncludeEscalators(true)
                                                  .setIncludeStairs(false)
                                                  .setIncludeRamps(true)
                                                  .setIncludeElevators(true)
                                                  .setItineraryOptimization(true)
                                                  .build()

    //Build a route request
    let routeRequest = MNRouteRequest(propertyId: propertyId, startWaypoint: fromCurrentLocation ? nil : start, destinationWaypoints: pois, routingOptions: routingOptions, routingConstraints: MNRoutingConstraints.emptyInstance(), isFromCurrentLocation: fromCurrentLocation)

    DispatchQueue.global(qos: .userInteractive).async {
       CoreApi.RoutingManager.requestRoute(request: routeRequest, routingRequestCallback: self)
    }
}

3. Handling Route Request Callbacks

In previous versions, route request callbacks were handled like this:

extension YourViewController : RoutingRequestCallback {
    func onSuccess(routeResponse: MNRouteResponse) {

        if routeResponse.errorType == .noError {
            routes = routeResponse.routes
        }

        MapstedMapApi.shared.handleRouteResponse(routeResponse: routeResponse)
    }

    func onError(errorCode: Int, errorMessage: String, alertIds: [String]) {

        MapstedMapApi.shared.handleRouteError(errorCode: errorCode, errorMessage: errorMessage, alertIds: alertIds)

    }
}

In SDK v6.2.0+, this has been simplified to:

extension YourViewController : RoutingRequestCallback {
    func onSuccess(routeResponse: MNRouteResponse) {
        if let routeError = routeResponse.routeError {
            print("#RouteRequestDelegate: onSuccess - \(routeError.isSuccessful)")
        }
    }

    func onError(routeResponse: MNRouteResponse) {
        if let routeError = routeResponse.routeError {
            print("#RouteRequestDelegate: onError - \(String(describing: routeError.errorMessage))")
        }
    }
}

4. Start Navigation

In previous versions, start-navigation was handled like this:

func startNavigation() {

    guard let route = routes.first else {
        return
    }

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
        MapstedMapApi.shared.setCameraAutofollow(enabled: true)
        CoreApi.RoutingManager.startNavigation(route: route, routingStatusCallback: self)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            MapstedMapApi.shared.drawCurrent(switchFloor: true)
        }
    }

}

With SDK v6.2.0+, this has been changed to:

func startNavigation() {

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
        MapstedMapApi.shared.startNavigation(fromPosition: nil)
        CoreApi.RoutingManager.addNavigationCallbackListener(listener: self)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            MapstedMapApi.shared.drawCurrent(switchFloor: true)
        }
    }

}

5. Stop Navigation

In previous versions, stop-navigation was handled like this:

func stopNavigation() {
    MapstedMapApi.shared.stopNavigation(finalPosition: nil)
    MapstedMapApi.shared.setCameraAutofollow(enabled: false)
}

With SDK v6.2.0+, this has been changed to:

func stopNavigation() {
    MapstedMapApi.shared.stopNavigation(finalPosition: nil)
}

6. Handling Navigation Callbacks

In previous versions, navigation callbacks were handled like this:

extension YourViewController: RoutingStatusCallback {
    func onRoutingStatus(isRoutingModeOn: Bool, latestRouteResponse: MNRouteResponse) {
        print("#NavDelegate - onRoutingStatus: \(isRoutingModeOn)")
    }

    func onRouteInstructionReceived(routeNode: MNRouteNode, nextRouteNode: MNRouteNode?) {
        print("#NavDelegate - onRouteInstructionReceived - routeNode.instruction - \(routeNode.instruction)")
        print("#NavDelegate - onRouteInstructionReceived - routeNode: \(routeNode.distTime?.distanceInMeters) mtrs - \(routeNode.distTime?.timeInMinutes) mins")

        guard let nextRouteNode = nextRouteNode else {
            return
        }

        print("#NavDelegate - onRouteInstructionReceived - nextRouteNode.instruction: \(nextRouteNode.instruction)")
        print("#NavDelegate - onRouteInstructionReceived - nextRouteNode: \(nextRouteNode.distTime?.distanceInMeters) mtrs - \(nextRouteNode.distTime?.timeInMinutes) mins")
    }

    func onRouteSegmentReached(currentRouteSegment: MNRouteSegment, visitedRouteSegments: [MNRouteSegment], upcomingRouteSegments: [MNRouteSegment]) {

    }

    func onUserProgressAlongRoute(routeUserProgress: MNRouteUserProgress) {
        print("#NavDelegate - onUserProgressAlongRoute - routeUserProgress - \(routeUserProgress.getDistanceTimeToNextKeyPoint().distanceInMeters) mtrs -  \(routeUserProgress.getDistanceTimeToNextKeyPoint().timeInMinutes) mins")
    }

    func onRouteRecalculation(newRouteResponse: MNRouteResponse) {
        print("#NavDelegate - onRouteRecalculation called")
    }

    func onDestinationReached(waypoint: MapstedCore.MapstedWaypoint) {
        print("#NavDelegate - onDestinationReached - waypoint: \(waypoint.getName())")
    }
}

With SDK v6.2.0+, this has been changed to:

var instructionString: String = ""

extension YourViewController: NavigationCallback {
    func onNavigationInitSuccess(state: MNNavigationState) {
        print("#NavDelegate: Success - \(String(describing: state.description()))")
    }

    func onNavigationInitFailure(error: MNNavigationError) {
        print("#NavDelegate: Failure - \(error.description())")
    }

    func onRouteSegmentReached(currentSegment: MNRoutePathSegment, visitedSegments: [MNRoutePathSegment], upcomingSegments: [MNRoutePathSegment]) {
        print("#NavDelegate: SegmentReached - \(currentSegment.floorLabel)")
    }

    func onUserProgressAlongRoute(state: MNNavigationState) {   
        //Here are some of the details that can be obtained from the state object of type MNNavigationState         
        // state.propertyId - The propertyId for the currently active navigation
        // state.buildingId - The buildingId for the currently active navigation
        // state.isActive - The boolean to check whether the navigation is currently active.
        // state.curRoutePath - The current route path for the currently active navigation.
        // state.nextInstruction - The next instruction for the currently active navigation.
        // state.afterNextInstruction - The next to next instruction for the currently active navigation.
        // state.userPoint - The location of the user for the currently active navigation.
        // state.isFirstSegment - The boolean to check whether this is first segment for the currently active navigation.
        // state.isIntermediarySegment - The boolean to check whether this is intermediary segment for the currently active navigation.
        // state.isLastSegment - The boolean to check whether this is last segment for the currently active navigation.
        // state.distTimeToNextInstruction - The distance and time to next instruction for the currently active navigation.
        // state.distTimeToDestination - The distance and time to destination for the currently active navigation.

        if instructionString == "" {
            if let nextInst = state.nextInstruction, let nextInstText = nextInst.getInstruction().text {
                instructionString = nextInstText
            }
        }
        let instructionForDisplay =  instructionString + " in " + "\(state.distTimeToNextInstruction.distanceMeters) mtrs, \(state.distTimeToNextInstruction.timeMinutes) mins"
        print("#NavDelegate: ProgressAlongRoute - instruction: \(instructionForDisplay)")
    }

    func onRouteInstruction(currentInstruction: MNRoutePointInstruction, nextInstruction: MNRoutePointInstruction, afterNextInstruction: MNRoutePointInstruction) {
        guard let instructionText = nextInstruction.getInstruction().text else {
            instructionString = ""
            return
        }
        instructionString = instructionText
        if let distanceTime = currentInstruction.toNextInstructionDistanceTime {
            let instructionForDisplay =  instructionString + " in " + "\(distanceTime.distanceMeters) mtrs, \(distanceTime.timeMinutes) mins"
            print("#NavDelegate: RouteInstruction - instruction: \(instructionForDisplay)")
        }
        else {
            let instructionForDisplay =  instructionString
            print("#NavDelegate: RouteInstruction - instruction: \(instructionForDisplay)")
        }
    }

    func onRouteRecalculation(state: MNNavigationState, newRoute: MNRoute, routePathType: MNRoutePathType) {
        print("#NavDelegate: RouteRecalculation - state: \(String(describing: state.description())) - newRoute: \(String(describing: newRoute.optimalRoute)) - afterNextIroutePathType: \(routePathType)")
    }

    func onDestinationReached(destination: MapstedCore.MapstedWaypoint) {
        print("#NavDelegate: DestinationReached - destination: \(destination.getName())")
    }
}