mapbox / mapbox-navigation-ios

Turn-by-turn navigation logic and UI in Swift on iOS
https://docs.mapbox.com/ios/navigation/
Other
860 stars 310 forks source link

[Bug]: MapboxNavigationProvider automatically prompt user for foreground location permission #4714

Closed fbeccaceci closed 1 week ago

fbeccaceci commented 2 weeks ago

Mapbox Navigation SDK version

3.3.0

Steps to reproduce

Just instantiate an instance of MapboxNavigationProvider

let navigationProvider = MapboxNavigationProvider(coreConfig: .init(
    locationSource: .simulation(initialLocation: nil)
))

Expected behavior

Nothing happen and i can manage myself the location permission.

Actual behavior

The app shows the popup to grant foreground location permission.

Is this a one-time issue or a repeatable issue?

repeatable

fbeccaceci commented 2 weeks ago

This is a problem because i show a navigationMapView to the user in the first screen of the app, initialized like this

let mapboxNavigation = navigationProvider.mapboxNavigation

self.navigationMapView = .init(
      location: mapboxNavigation.navigation().locationMatching.map(\.location).eraseToAnyPublisher(),
      routeProgress: mapboxNavigation.navigation().routeProgress.map(\.?.routeProgress).eraseToAnyPublisher(),
      heading: navigationProvider.navigation().heading,
      predictiveCacheManager: navigationProvider.predictiveCacheManager
    )

to show the user a map, without any navigation behavior. Then if the user grants location permission i can show theire location on the map and do some navigation, but right now as the app loads the user is directly asked to grant the permission and i cannot manage it myself

JanTG1 commented 1 week ago

@fbeccaceci I have no Idea and haven't tried anything similar, but as a Mapbox User myself, I would guess it is due to the navigationProvider's Location handling, which needs permissions to work. You might want to build your own placeholder location provider instead of the one from your navigationProvider to avoid that.

kried commented 1 week ago

Hi @fbeccaceci

As mentioned above, you can implement a custom location client that does not request location permission and pass it to MapboxNavigationProvider

MapboxNavigationProvider(
            coreConfig: .init(
                locationSource: .custom(customLocationClient)
            )
        )

You can copy the default SDK LocationClient initialization and remove manager.requestWhenInUseAuthorization() call. Then it will be the responsibility of your app to request the required location permission at a suitable moment.


The other possible scenario is to custom initialize the NavigationMapView instance. You can create it even without MapboxNavigationProvider instance. You can pass empty publisher implementations and recreate NavigationMapView instance later once the location permission is requested:

let emptyLocationPublisher: AnyPublisher<CLLocation, Never> = Empty().eraseToAnyPublisher()
let emptyRouteProgress: AnyPublisher<RouteProgress?, Never> = Empty().eraseToAnyPublisher()
navigationMapView = .init(location: emptyLocationPublisher, routeProgress: emptyRouteProgress)