Offline routing features
In addition to the online-only RoutingEngine, there is also an equivalent for offline use cases available: the OfflineRoutingEngine. This offline version is designed to offer the same robust routing capabilities as its online counterpart, ensuring seamless navigation even without an internet connection.
NoteYou can only calculate routes on already cached or preloaded offline maps data. When you use only cached map data, it may happen that not all tiles are loaded for the lower zoom levels. In that case, no route can be found until also the lower zoom levels are loaded - even if you see the map. With offline maps this cannot happen and the required map data is guaranteed to be available for the downloaded region. Therefore, it is recommended to not rely on cached map data.
The OfflineRoutingEngine can be constructed in the same straightforward manner as the RoutingEngine:
private var routingEngine: RoutingProtocol
private var onlineRoutingEngine: RoutingEngine
private var offlineRoutingEngine: OfflineRoutingEngine
...
do {
try onlineRoutingEngine = RoutingEngine()
} catch let engineInstantiationError {
fatalError("Failed to initialize routing engine. Cause: \(engineInstantiationError)")
}
do {
// Allows to calculate routes on already downloaded or cached map data.
try offlineRoutingEngine = OfflineRoutingEngine()
} catch let engineInstantiationError {
fatalError("Failed to initialize offline routing engine. Cause: \(engineInstantiationError)")
}
// By default, use online routing engine.
routingEngine = onlineRoutingEngine
// Detect whether we should search online or offline.
setNetworkUpdateHandler()
NoteTransit routes (via
TransitRoutingEngine) and EV routes (viaElectricVehicleOptionsinRoutingOptions) are not yet supported and only work online. TheOfflineRouteEnginewill fail withRoutingError.invalidParameterin case of unsupported transport modes.
The OfflineRoutingEngine provides the same interfaces as the RoutingEngine, but the results may slightly differ as the results are taken from already downloaded or cached map data instead of initiating a new request to a HERE backend service.
This way the data may be, for example, older compared to the data you may receive when using the RoutingEngine. On the other hand, this class provides results faster - as no online connection is necessary.
However, the resulting routes contain only an empty list of maneuvers. If you need to get maneuvers during guidance, you can get them directly from the Navigator or VisualNavigator via the provided nextManeuverIndex. This is shown in the Navigation section.
All available interfaces of the OfflineRoutingEngine are also available in the RoutingEngine and both engines adopt the same protocol. This makes it easy to switch between both engine instances as we will show below.
NoteTo get a quick overview of how all of this works, you can take a look at the RoutingHybridExample.swift class. It contains all code snippets shown below and it is part of the "RoutingHybrid" example app you can find on GitHub.
Below we show how to switch between OfflineRoutingEngine and RoutingEngine. For example, when you are on the go, it can happen that your connection is temporarily lost. In such a case it makes sense to calculate routes on the already cached or downloaded map data with the OfflineRoutingEngine.
To do so, first you need to check if the device has lost its connectivity. As a second step you can use the preferred engine:
// Sets the OfflineRoutingEngine as main engine when the device is not connected, otherwise this will set the
// RoutingEngine that requires connectivity.
private func setRoutingEngine() {
if isDeviceConnected {
routingEngine = onlineRoutingEngine
} else {
routingEngine = offlineRoutingEngine
}
}
Here, we use a boolean value isDeviceConnected to store if the device is connected or not.
Now, you can execute the same code on the current routingEngine instance, as shown in the previous sections above.
NoteIf the device is offline, the online variant will not find routes and will report an error. Vice versa, when the device is online, but no cached or preloaded map data is available for the area you want to use, the offline variant will report an error as well.
Note that the code to check if the device is online or not is left out here. You may use a third-party API for this or try to make an actual connection - and when that fails, you can switch to the OfflineRoutingEngine - or the other way round: you can try offline routing first to provide a fast experience for the user, but when no map data is available, you can try online.
NoteYou can find the "RoutingHybrid" example app on GitHub.
Updated 10 hours ago