mapboxmapbox-iosturn-by-turnmapbox-navigation

Duplicate voice problem in Mapbox Navigation IOS


I use map box navigation turn by turn! I need to add waypoints to the navigation map so that they show up in the active navigation state! I added a layer with points to the map using the addSpots method. Points are displayed on the map as I need. But a problem arose: when I close the navigation and then open it again, the voice instructions are duplicated and superimposed on one another, the more times I close and open the navigation, the more voice layers!

As I understand it, when the controller is closed, the navigation does not end, and when a new session is opened, it overlaps the first one! Maybe I'm not completing the navigation correctly or adding the layer to the map incorrectly, because when I remove the addSpots method, the problem with voice duplication disappears!

What can I try next?

here is my navigationController:

import Foundation
import UIKit
import XamoomSDK
import MBProgressHUD
import FirebaseAuth
import NotificationCenter
import MapboxDirections
import MapboxCoreNavigation
import MapboxNavigation
import MapboxMaps
import CoreLocation
import MBProgressHUD

class BasicViewController: UIViewController {
    
    var wayPoint: [Waypoint] = []
    var spots: [XMMSpot] = []
    var customImageMarker: UIImage?
    var layer: [String] = []
    
    convenience init(waypoints: [Waypoint], spots: [XMMSpot], customImageMarker: UIImage, layer: [String]) {
        self.init(nibName: nil, bundle: nil)
        self.wayPoint = waypoints
        self.spots = spots
        self.customImageMarker = customImageMarker
        self.layer = layer
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        requestRoute()
        
    }
    
    func requestRoute() {
        let navigationRoutOptions = NavigationRouteOptions(waypoints: wayPoint)
        
        Directions.shared.calculate(navigationRoutOptions) { [weak self] (_, result) in
            switch result {
            case .failure(let error):
                print(error.localizedDescription)
            case .success(let response):
                guard let strongSelf = self else {
                    return
                }
                
                let navigationService = MapboxNavigationService(routeResponse: response, routeIndex: 0, routeOptions: navigationRoutOptions, credentials: NavigationSettings.shared.directions.credentials, simulating: .none)
                
                let navigationOptions = NavigationOptions(navigationService: navigationService)
                let navigationViewController = NavigationViewController(for: response, routeIndex: 0, routeOptions: navigationRoutOptions,
                                                                        navigationOptions: navigationOptions)
                
                navigationViewController.delegate = strongSelf
                
                self?.addSpots(navViewController: (navigationViewController))
                
                navigationViewController.modalPresentationStyle = .fullScreen
                
                navigationViewController.routeLineTracksTraversal = true
                
                strongSelf.present(navigationViewController, animated: true, completion: nil)
            }
        }
    }
    
    func addSpots(navViewController: NavigationViewController) {
        navViewController.navigationMapView?.mapView.mapboxMap.onEvery(event: .styleLoaded) {  _ in
          for spot in self.spots {
              let style = navViewController.navigationMapView?.mapView.mapboxMap.style
            try? style?.addImage((self.customImageMarker!), id: "markerimage", stretchX: [], stretchY: [])

            let someCoordinate = CLLocationCoordinate2DMake(spot.latitude, spot.longitude)
            let point = Point(someCoordinate)

            var feature = Feature(geometry: Geometry.point(point))
            feature.identifier = .string(spot.name)

            var source = GeoJSONSource()
            source.data = .feature(feature)
            try? navViewController.navigationMapView?.mapView.mapboxMap.style.addSource(source, id: spot.name)
            self.layer.append(spot.name)

            var layer = SymbolLayer(id: spot.name)
            layer.source = spot.name
            layer.iconImage = .constant(.name("markerimage"))
            layer.iconAnchor = .constant(.bottom)
            layer.textField = .constant(spot.name)
            layer.iconAllowOverlap = .constant(true)
            try? navViewController.navigationMapView?.mapView.mapboxMap.style.addLayer(layer)
          }
        }
    }
}

extension BasicViewController: NavigationViewControllerDelegate {
    func navigationViewControllerDidDismiss(_ navigationViewController: NavigationViewController, byCanceling canceled: Bool) {
        dismiss(animated: true, completion: nil)
    }
}

I try navigationServices.stop() when navigationController is dismissed, its not help.


Solution

  • The problem was that I didn’t close the navigation view correctly, namely, I didn’t remove it from the super view, this led to a memory leak and therefore the voice overlapped many times on itself.