Start navigating

The Sygic iOS SDK supports navigation on pedestrian and car routes. Using this feature, your app can check the current device position against a calculated route and provide just-in-time navigational instructions, both as visual and voice instructions. Turn-by-Turn Navigation Mode, which takes the calculated route and matches the current position against the route is supported for walking and driving.


class NaviViewController: UIViewController, SYNavigationDelegate {

    func startNavigation(with route: SYRoute) {
        SYNavigation.shared().delegate = self
        SYNavigation.shared().start(with: route)
    }
}

Do not forget to add the route to your MapView.

let mapRoute = SYMapRoute(route: route, type: .primary)
mapView.add(currentRoute)

mapView.cameraMovementMode = .followGpsPosition

SYNavigationDelegate protocol
SYNavigation notifies the client of navigation events through its delegates that implement the SYNavigationDelegate protocol. The delegate protocol include methods such as:

  • didUpdatePositionInfo: - Called when the current positionInfo has changed.
  • didUpdateSpeedLimit: - Called when the speed limit has changed.
  • didUpdateDirection: – Called when current instruction has changed.
  • didUpdateSignpost: - Called that the signopostInfo has changed.
  • didUpdateRadar: - Called that the radar on the route has been updated.
  • didUpdateSharpCurve: - Called when a danger turn is ahead on current route.
  • didPassWaypointWithIndex: - Called when turn-by-turn navigation waypoint is passed.
  • navigationManagerDidReachFinish: - Called when turn-by-turn navigation destination is reached.
  • didFindBetterRoute: - Called when better route has been found.
  • didUpdateHighwayExit: - Called when hihgway exit info has changed. Event does not fire when route is calculated.
  • didUpdateRoute: - Called when current navigation route is changed or removed.
  • didUpdateTransportMode: - Called when transport mode has changed. For example you switch from car to pedestrian.
  • didUpdateOnRouteInfo: - Called when position on current navigation route has changed.

SYNavigationAudioFeedbackDelegate protocol
To get audio notifications and voice navigation, you have ti listen to SYNavigationAudioFeedbackDelegate. If you set these to NO, audio warnings will be disabled.

  • shouldPlayWarningAudioFeedback: - Called when navigation manager has warning audio feedback is ready to play.
  • shouldPlaySpeedLimitAudioFeedback: - Called when speed limit warning audio feedback is ready to play.
  • shouldPlayBetterRouteAudioFeedback: - Called when better route audio feedback is ready to play.
  • shouldPlayTrafficAudioFeedback: - Called when traffic change audio feedback is ready to play.
  • shouldPlayInstructionAudioFeedback - Called when navigation instruction audio feedback is ready to play.

Map Matching During Navigation

Map Matching is automatically enabled in both navigation mode and tracking mode. In simulation mode, the map-matched position is simulated along the route with a user-defined speed.

Audio Warnings

Sygic Mobile SDK enables you to set custom audio notifications for warnings. If the methods of above mentioned SYNavigationAudioFeedbackDelegate are set to YES, there will be played some default set audio notifications. To use your custom ones, you have to use SYAudioSettings class. SYAudioSettings class provides a possibilities to set a custom voice for various cases. You can choose between prerecorded audio files (OGG or WAVE format) or TTS voice. See the SYAudioSettings API reference for more info.

Following example shows, how to set an custom TTS voice, when you exceed the speed limit.

SYAudioSettings* audioSettings = [SYAudioSettings new];
    audioSettings.speedLimitWarning.mode = SYAudioWarningModeUseTts;
    audioSettings.speedLimitWarning.ttsText = @"Slow down!";

If you would like to use custom precorded audio file, you need to choose it from path:

SYAudioSettings* audioSettings = [SYAudioSettings new];
    audioSettings.speedLimitWarning.warningSoundPath = [[NSBundle mainBundle] pathForResource:@"/example/example/example" ofType:@"wav"];

Voice Instructions

Voice instructions are available in the Sygic SDK as voice packages. Voice packages are available in two forms: pre-packaged or downloadable through the voice catalog. You can set a voice package to be used for navigational instructions. However, if a package is not set, the Sygic SDK sets the navigation voice language to US English, which is pre-packaged with the Sygic SDK.

The SYVoicePackage class encapsulates spoken voices that can be used for navigation guidance. It contains information such as name, gender, and the spoken language. This information can be accessed through its class properties.

A list of loaded SYVoicePackage instances can be accessed by using the SYVoiceCatalog singleton instance. Multiple voice package can be loaded to the device, but only one can be selected for navigation voice playback. A SYVoicePackage can be used through the voicePackage property. Each SYVoicePackage is represented by a unique ID in the packageId property.

The Sygic SDK supports two types of voice packages: text-to-speech or pre-recorded. Pre-recorded voice skins provide basic maneuver instructions, such as "turn right in 100 meters", while text-to-speech voices also support spoken street names, such as "turn right in 100 meters onto Wall Street".

The following is an example of how to use a SYVoicePackage with the navigation manager:

class VoicesViewController: UIViewController, SYVoiceCatalogDelegate {
    var voicePackages: [SYVoicePackage]()

    func viewDidLoad() {
        // Get a list of all available voices
        SYVoiceCatalog.shared().delegate = self
        SYVoiceCatalog.shared().getAvailableVoicePackages()
    }

    func downloadPackage(with index: Integer) {
        let voicePackage = voicePackages[index]
        SYVoiceCatalog.shared().installVoicePackage(voicePackage)
    }

    // MARK: - SYVoiceCatalogDelegate

    func voiceCatalog(_ voiceCatalog: SYVoiceCatalog, didgetAvailableVoicePackages packages: [SYVoicePackage], from task: SYTask) {
        voicePackages = packages
    }

    func voiceCatalog(_ voiceCatalog: SYVoiceCatalog, didInstallVoicePackage package: SYVoicePackage, result: SYPackageInstallResult, from task: SYTask) {
        // set the downloaded voice as your current
        SYVoiceCatalog.shared().setCurrentVoice(voicePackage)
    }
}

If the voice is set, in navigation mode the voice instructions are played automatically.

This is a list of the potential TTS languages that are supported. Actual audio playback depends on the supported languages in the user's installed version of iOS.

  • English (US)
  • English (UK)
  • English (AUS)
  • French (France)
  • French (Canada)
  • German
  • Belgian
  • Bahasa Indonesia
  • Hungarian
  • Dutch
  • Arabic
  • Finnish
  • Spanish (Spain)
  • Spanish (Mexico)
  • Italian
  • Norwegian
  • Portugese (Portugal)
  • Portugese (Brazil)
  • Russian
  • Swedish
  • Finnish
  • Danish
  • Korean
  • Hindi
  • Chinese (Taiwanese Mandarin)
  • Chinese (Hong Kong Mandarin)
  • Turkish
  • Czech
  • Polish

Traffic

The Sygic iOS SDK offers real-time traffic flow and congestion overlays. Traffic information can be displayed on the SYMapView (where available) by calling the enableTraffic method. While the Sygic SDK requires a network data connection to download real time traffic information, the visualization may continue to be displayed even if a connection is lost - until the traffic events expire, or the visibility is toggled.

BOOL enableTraffic = NO;
Map view with traffic

For further information see the SYTraffic reference.

Signposts

This section provides guidelines on how to use the Sygic Mobile SDK Signpost object to present visual maneuver instructions which match with the audible voice instruction during turn-by-turn guidance. Signs represent textual and graphic information posted along roads. The information is always represented as text, but may originate from a graphical icon. Signpost information may be used for route guidance (both audible and visual guidance) and map display. A navigation system may prefer using the signpost text rather than the street/ramp name as the latter may not always match what is on the sign in reality and may confuse a user. The signpost feature supports the user navigating through complex situations and provides a conformation for a maneuver by presenting the same direction information as shown on the street signs in reality.

Based on the map attributes, the Sygic iOS Mobile SDKs aggregate the following information into a Signpost object:

  • Route number
  • Exit number
  • Exit name
  • Pictogram
  • Place name

Following example shows, how to get these information from the data structure, which the iOS SDK offers.

class NaviViewcontroller: UIViewController, SYNavigationDelegate {
    let route: SYRoute

    // ...

    func viewDidLoad() {
        SYNavigation.shared().delegate = self
        SYNavigation.shared().start(with: route)
    }

    // MARK: - SYNavigationDelegate

    func navigation(_ navigation: SYNavigation, didUpdateSignpost signpostInfo: [SYSignpost]?) {
                resetSignpost()
        guard let signpost = signpost else { return }

        textColor = signpost.textColor
        backgroundColor = signpost.backgroundColor
        distanceToSignpost = signpost.distance

        var titles = [String]()
        var routeNumbers = [String]()
        var exitNames = [String]()
        var pictograms = [String]()

        for element in signpost.elements {
            switch element.type {
            case .placeName, .streetName, .otherDestination:
                if let text = element.text {
                    titles.append(text)
                }
            case .routeNumber:
                if let routeNumber = element.text {
                    routeNumbers.append(routeNumber)
                }
            case .exitName:
                if let exitName = element.text {
                    exitNames.append(exitName)
                }
            case .exitNumber:
                if let number = element.text {
                    highwayExit = number
                }
            case .pictogram:
                pictograms.append(element.pictogram.toSymbol())
            case .lineBreak:
                break
            }
        }

        self.title = titles.joined(separator: ", ")
        self.routeNumbers = routeNumbers.prefix(4).joined(separator: " ")
        self.exitNames = exitNames.joined(separator: ", ")
        self.pictograms = pictograms.prefix(4).joined(separator: " ")
    }
}

Directions

To provide more detailed information in signpost, you can display the direction which the user should follow. The Directions feature allows developers to define and display routes between a start and a destination point within their application. NavigationManager.OnDirectionListener can return following information:

  • Direction distance
  • Next direction distance
  • Maneuver type - see the all available ManeuverTypes
  • Road name
  • Next road name

Following example shows, how to get these information from the data structure, which the iOS SDK offers.

class NaviViewcontroller: UIViewController, SYNavigationDelegate {
    let route: SYRoute

    // ...

    func viewDidLoad() {
        SYNavigation.shared().delegate = self
        SYNavigation.shared().start(with: route)
    }

    // MARK: - SYNavigationDelegate

    func navigation(_ navigation: SYNavigation, didUpdateDirection directionInfo: SYInstruction?) {
        guard let directionInfo = directionInfo else { return }

        if let primaryManeuver = directionInfo.primaryManeuver {
            let distanceToInstruction = primaryManeuver.distanceToManeuver
            let instructionType = primaryManeuver.type
            let currentRoadName = primaryManeuver.road?.roadName
            let nextRoadName = primaryManeuver.nextRoad?.roadName

            print("Distance to direction of type \(type) on the road \(currentRoadName) is \(distanceToInstruction). Next road is \(nextRoadName)")
        }
    }
}
Signpost

Junction View

Junction view is one of our advanced safety features. When you are approaching a complex highway intersection, a full screen diagram of the intersection will appear on the screen showing you in detail which lane you should be in. It guides you into the correct lane to make driving easier, safer and less stressful.

func navigation(_ navigation: SYNavigation, didUpdateSignpost signpostInfo: [SYSignpost]?) {
        if let junctionInfo = signpostInfo?.last?.junctionInfo {

            let svgNames = svgNamesFromJunctionInfo(junctionInfo)

            backgroundImage = backgroundImageFromJunctionBackground(junctionInfo.background, andRoadSvgName: svgNames.roadSvgName)
            roadImage = UIImage.imageFromSVG(svgNames.roadSvgName, size: svgSize)
            arrowImage = UIImage.imageFromSVG(svgNames.arrowSvgName, size: svgSize)

            roadImage = imageWithImage(roadImage, scaledToSize: squareSvgSize)
            arrowImage = imageWithImage(arrowImage, scaledToSize: squareSvgSize)
    }
}

 private func backgroundImageFromJunctionBackground(_ junctionBackground: SYJunctionBackground, andRoadSvgName roadSvgName: String) -> UIImage? {

        var imageName = "jw"
        if junctionBackground == .city {
            imageName.append("-city")
        }
        imageName.append(".jpg")

        return UIImage(named: imageName)
    }

private func svgNamesFromJunctionInfo(_ junctionInfo: SYJunctionInfo) -> (roadSvgName: String, arrowSvgName: String) {

        let fromLanes = junctionInfo.fromLanesCount
        let toLanesRight = junctionInfo.toRightLanesCount
        let toLanesLeft = junctionInfo.toLeftLanesCount
        let roadEnd = junctionInfo.turnType == .exit
        let arrowLeft = junctionInfo.turnDirection == .left

        let svgRoad = String.init(format: "%d_%d_%d_%@", fromLanes, toLanesRight, toLanesLeft, roadEnd ? "E" : "B")
        let svgArrow = svgRoad.appending(arrowLeft ? "_L" : "_R")

        return (svgRoad, svgArrow)
}

Speed Limit

Speed limits indicate the legal speed for a vehicle. Depending on the country the values are given in mph or kph.
A speed limit has the following attributes:

  • speedLimit - Value of the speed limit. Range: 1 - 999. For roads that allow an unlimited speed, the speed limit value is 999. A value of 998 is applied to ramps if there is neither a posted speed limit nor a legal speed limit.
  • isInMunicipality - Represents, if you are headin through Municipality, returns NO if you are not.
  • country - Get the region, in which you want to see the speedlimit. You can choose if you are in America or rest of the world. See the SYSpeedLimitCountry enum in API reference.

Following example shows, how to get the current speed limit.

class NaviViewController: UIViewController, SYNavigationDelegate {

    func viewDidLoad() {
        // make sure you're the delegate of the SYNavigation module, so you'll receive all the needed updates
        SYNavigation.shared().delegate = self
    }

    // MARK: - SYNavigationDelegate

    func navigation(_ navigation: SYNavigation, didUpdate limit: SYSpeedLimit?) {
        guard let info = limit else { return }

        let speedLimit = info.speedLimit
        let isInAmerica = (info.country == .america)
        let isInMunicipality = info.isInMunicipality
    }
}

Warning settings

Maybe you might want to change the settings to the warnings you get during navigation. SYWarningSettings is a base class for warning notification settings. To access these settings you have to use [SYNavigation sharedNavigation] instance.

SYPoiOnRouteSettings enables to change some POI on route settings.

  • maxCount - Poi on Route max search poi count.
  • maxDistance - Poi on Route max search distance.
[SYNavigation sharedNavigation].settings.poiOnRoute.maxDistance = 100;

SYDirectionSettings

  • nextDirectionDistance - Set the minimal distance between first end second instruction to be notified.
[SYNavigation sharedNavigation].settings.direction.nextDirectionDistance = 5;

SYSpeedLimitWarningSettings

  • speedLimitDiffInCity - Set diff speed above maximum allowed speed to be notified as speeding in city.
  • speedLimitDiff - Set diff speed above maximum allowed speed to be notified as speeding.
  • nextSpeedLimitDistance - Set next speed limit search distance ahead vehicle.
  • nextSpeedLimitDistanceInCity - Set distance how far will look for other speed limit ahead vehicle in city.
[SYNavigation sharedNavigation].settings.speedLimit.speedLimitDiffInCity = 5;

SYSpeedCameraWarningSettings

  • searchDistanceInCity - Set Speed cameras search distance ahead vehicle in city.
  • searchDistance - Set Speed cameras search distance ahead vehicle.

SYRailwayCrossingWarningSettings

  • searchDistance - Set Railway crossing search distance ahead vehicle.
[SYNavigation sharedNavigation].settings.railway.searchdistance = 300;

Report Incident

Our Speed Camera database consists of more than 60 000 fixed speed cameras, red light cameras and average speed checks all over the world. On top of that, the community reports tens of thousands of additional mobile speed cameras and police checks every day. So, if you want to help to make our database bigger, use following example to report an incident. As parameter you can choose in which direction it happened on the road.

  • location - The exact SYGeoCoordinate position of the incident.
  • type - Type of the incident you want to report. See the available SYIncidentType in API reference.
  • direction - Indicates whether the incident happened in my direction or opposite direction.
SYNavigation.shared().delegate = self
SYNavigation.shared().reportIncident(atLocation: currentCoordinate, type: .camera, direction: .myDirection)