Migration Guide
Mappedin SDK for iOS version 6.0 is a major release that includes a number of changes to the SDK. It uses a GeoJSON-based rendering engine, rebuilt from the ground up. It works in unison with MapLibre which enables outdoor base maps as well as data visualization features. By using GeoJSON as the core data format, v6 can integrate with existing external data sources. This guide explains the steps needed to migrate from version 5.
Initialization Changes
The options for getting a map have changed. getVenue() has been replaced by getMapData().
v5 Initialization
// See Trial API key Terms and Conditions
// https://developer.mappedin.com/api-keys/
mapView.loadVenue(options:
MPIOptions.Init(
clientId: "5eab30aa91b055001a68e996",
clientSecret: "RJyRXKcryCMy4erZqqCbuB1NbR66QTGNXVE0x3Pg6oCIlUR1",
venue: "mappedin-demo-mall"
),
showVenueOptions: MPIOptions.ShowVenue(multiBufferRendering: true, outdoorView: MPIOptions.OutdoorView(enabled: true), shadingAndOutlines: true))
}
v6 Initialization
// See Trial API key Terms and Conditions
// https://developer.mappedin.com/docs/demo-keys-and-maps
let options = GetMapDataWithCredentialsOptions(
key: "5eab30aa91b055001a68e996",
secret: "RJyRXKcryCMy4erZqqCbuB1NbR66QTGNXVE0x3Pg6oCIlUR1",
mapId: "mappedin-demo-mall"
)
// Load the map data.
mapView.getMapData(options: options) { [weak self] r in
guard let self = self else { return }
if case .success = r {
print("getMapData success")
// Display the map.
self.mapView.show3dMap(options: Show3DMapOptions()) { r2 in
if case .success = r2 {
print("show3dMap success - Map displayed")
} else if case .failure(let error) = r2 {
print("show3dMap error: \(error)")
}
}
} else if case .failure(let error) = r {
print("getMapData error: \(error)")
}
}
Component Access
MPIData.<collection> has been replaced by MapData.getByType(<collection>)
For example:
In v5 access nodes using MPIData.nodes, which contains an array of Node objects.
In v6 access nodes using mapData.getByType<Node>(MapDataType.Node), which returns an array of Node objects.
Mappedin.getCollectionItemById is replaced by mapData.getById(<collection>, id)
The following classes have been redesigned. Refer to the chart below for a mapping of similar classes.
| v5 Component | v6 Component |
|---|---|
| MPIPolygon | Space |
| MPIMapGroup | FloorStack |
| MPIMap | Floor |
| MPICoordinates | Coordinate |
| MPINode | Node |
MPIState no longer exists.
UI Components
MPIFloatingLabelManager has been replaced with Labels.
MPIFloatingLabelManager.labelAllLocations() will be replaced with MapView.auto().
MPIMarkerManager has been replaced with Markers.
Tooltips have not been carried over from v5 and Markers should be used instead.
Updating UI Components
setPolygonColor, clearPolygonColor and other methods of changing the state of UI objects on the map is now performed using MapView.updateState(), which also supports initial for returning properties to their original state.
MPICameraManager.animate() has been renamed to Camera.animateTo().
MPIMarkerManager.animate() has been renamed to Markers.animateTo().
Interactivity
MapView.addInteractivePolygon() has been replaced by updating the state of each space to be interactive as shown below.
// Set all spaces to be interactive so they can be clicked
mapView.mapData.getByType(.space) { [weak self] (result: Result<[Space], Error>) in
guard let self = self else { return }
if case .success(let spaces) = result {
spaces.forEach { space in
self.mapView.updateState(space: space, state: GeometryUpdateState(interactive: true))
}
}
}
Event names passed from MapView.on() have been changed:
| v5 Event | v 6 Event |
|---|---|
E_SDK_EVENT.CLICK | Events.click |
E_SDK_EVENT.MAP_CHANGED , E_SDK_EVENT.MAP_CHANGED_WITH_REASON | Events.floorChange |
E_SDK_EVENT.OUTDOOR_VIEW_LOADED | Events.outdoorViewLoaded |
Stacked Maps
Stacked Maps APIs have been replaced with Multi Floor View along with the ability to control the visibility and altitude of floors. Refer to the Multi Floor View and Stacked Maps guides for more information.
Map Metadata
Classes containing enterprise map metadata have been renamed.
| v5 Component | v6 Component |
|---|---|
| MPICategory | EnterpriseCategory |
| MPILocation | EnterpriseLocation |
| MPIVenue | EnterpriseVenue |
Wayfinding & Directions
MapData.getDirections() only supports getting directions between two locations. For multi destination directions, use MapData.getDirectionsMultiDestination().
MPIJourneyManager is now Navigation.
Camera
v5 MPICameraManager.tilt in radians is replaced by v6 Camera.pitch in degrees. Camera.minPitch and Camera.maxPitch are now available to set the minimum and maximum pitch values.
v5 MPICameraManager.rotation in radians is replace in v6 by Camera.bearing in degrees Clockwise rotation is now positive.
v5 Camera.zoom, Camera.minZoom and Camera.maxZoom used meters from ground level. In v6 these now use mercator zoom level units.
The following camera methods and accessors have been renamed.
Search
MPISearchManager has been changed to Search. The results returned in SearchResult are more structured:
struct SearchResult {
let enterpriseCategories: [SearchResultEnterpriseCategory]?
let enterpriseLocations: [SearchResultEnterpriseLocations]?
let places: [SearchResultPlaces]
}
Multi Language
The methods to work with maps in multiple languages have been changed.
v6
// Specify a non default language when getting map data
let options = GetMapDataWithCredentialsOptions(
key: "key",
secret: "secret",
mapId: "mapId",
language: "en"
)
// Get supported languages
mapView.mapData.getByType(.enterpriseVenue) { [weak self] (result: Result<[EnterpriseVenue], Error>) in
guard let self = self else { return }
if case .success(let enterpriseVenue) = result {
enterpriseVenue.languages.forEach { language in
print("Language: \(language)")
}
}
}
// Change language
mapData.changeLanguage("es") { result in
switch result {
case .success:
print("Map language changed to Spanish")
case .failure(let error):
print("Error: \(error)")
}
}
Blue Dot
The Blue Dot system has been redesigned in v6. MPIBlueDotManager has been replaced by BlueDot, accessed through MapView.blueDot. The v6 API provides more granular control over the Blue Dot's appearance, a richer event system and asynchronous result callbacks.
Complete examples demonstrating Blue Dot can be found in the Mappedin iOS GitHub repo:
Class and API Changes
| v5 Component | v6 Component |
|---|---|
| MPIBlueDotManager | BlueDot |
| MPIOptions.BlueDot | BlueDotOptions |
| MPIPosition / MPICoordinates | BlueDotPositionUpdate |
MPIBlueDotManager.setState(state:) | BlueDot.follow() with FollowMode |
| MPIState.FOLLOW / MPIState.EXPLORE | FollowMode (.positionOnly, .positionAndHeading, .positionAndPathDirection, nil) |
Enabling Blue Dot
In v5, the Blue Dot is enabled through MPIBlueDotManager with minimal options. In v6, BlueDot.enable() accepts BlueDotOptions to customize the appearance and provides an asynchronous result callback.
v5:
mapView?.blueDotManager.enable(options: MPIOptions.BlueDot())
v6:
let options = BlueDotOptions(
accuracyRing: BlueDotOptions.AccuracyRing(color: "#2266ff", opacity: 0.25),
color: "#2266ff",
heading: BlueDotOptions.Heading(color: "#2266ff", opacity: 0.6),
initialState: .inactive,
radius: 12,
watchDevicePosition: false
)
mapView.blueDot.enable(options: options) { result in
if case .success = result {
print("BlueDot enabled")
}
}
Disabling Blue Dot
v6 introduces an explicit BlueDot.disable() method with a result callback.
mapView.blueDot.disable { result in
if case .success = result {
print("BlueDot disabled")
}
}
Updating Blue Dot Position
In v5, positions are provided through MPIPosition containing MPICoordinates. In v6, BlueDotPositionUpdate provides typed parameters for each field and supports partial updates.
v5:
let coords = MPICoordinates(latitude: 43.520124, longitude: -80.539517, accuracy: 2.0, floorLevel: 0)
let position = MPIPosition(timestamp: 1.0, coords: coords)
mapView?.blueDotManager.updatePosition(position: position)
v6:
let position = BlueDotPositionUpdate(
accuracy: .value(5.0),
floorId: .id("floor_id"),
heading: .value(90.0),
latitude: .value(43.520124),
longitude: .value(-80.539517)
)
mapView.blueDot.update(position: position, options: BlueDotUpdateOptions(animate: true)) { result in
if case .success = result {
print("BlueDot position updated")
}
}
Events
v5 relies on MPIMapViewDelegate methods for Blue Dot events. v6 uses an event-based system through BlueDotEvents, which provides more event types including click, error and follow change events.
v5:
func onBlueDotPositionUpdate(update: Mappedin.MPIBlueDotPositionUpdate) {
print(update.position)
}
func onBlueDotStateChange(stateChange: Mappedin.MPIBlueDotStateChange) {
print(stateChange.name)
print(stateChange.reason)
}
v6:
mapView.blueDot.on(BlueDotEvents.positionUpdate) { payload in
guard let payload = payload else { return }
let floorName = payload.floor?.name ?? "nil"
let heading = payload.heading.map { String(format: "%.0f°", $0) } ?? "nil"
print("position-update: (\(payload.coordinate.latitude), \(payload.coordinate.longitude)) floor=\(floorName) heading=\(heading)")
}
mapView.blueDot.on(BlueDotEvents.statusChange) { payload in
guard let payload = payload else { return }
print("status-change: \(payload.status.rawValue) (action: \(payload.action.rawValue))")
}
Camera Follow Mode
In v5, camera follow mode is controlled through MPIState. In v6, MPIState no longer exists and follow mode is controlled directly through BlueDot.follow() with FollowMode options that provide more granular control.
v5:
mapView?.blueDotManager.enable(options: MPIOptions.BlueDot(smoothing: true))
mapView?.blueDotManager.setState(state: MPIState.FOLLOW)
v6:
mapView.blueDot.follow(FollowMode.positionOnly)
Refer to the Blue Dot guide for full documentation on v6 Blue Dot capabilities.