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 introducedNavigationCallback
, which replacesRoutingStatusCallback
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())")
}
}