Skip to content

Commit 05f1c59

Browse files
authored
Switch to the Declarative Map Styling by default (#9219)
1 parent eaea546 commit 05f1c59

File tree

6 files changed

+100
-35
lines changed

6 files changed

+100
-35
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@
77
* MapboxNavigationCore now requires [MapboxMaps v11.13.0-beta.1](https://github.com/mapbox/mapbox-maps-ios/releases/tag/v11.13.0-beta.1)
88
* MapboxNavigationCore now requires [MapboxNavigationNative v324.13.0-beta.1](https://github.com/mapbox/mapbox-navigation-native-ios/releases/tag/v324.13.0-beta.1)
99

10+
### Map
11+
12+
* The SDK now uses [Declarative Map Styling](https://docs.mapbox.com/ios/maps/guides/styles/declarative-map-styling/) by default.
13+
If you want to customize the map content using declarative styling, e.g. to style non-navigation-related content, you should:
14+
* set `NavigationMapView.automaticallySetDeclarativeMapContent` to `false`,
15+
* subscribe to the `NavigationMapView.navigationStyleContent` updates,
16+
* add `currentNavigationStyleContent` to your `MapStyleContent`,
17+
* call `setMapStyleContent(content:)` with new map style content.
18+
For implementation details, refer to the [Declarative-Map](https://github.com/mapbox/mapbox-navigation-ios/blob/main/Examples/AdditionalExamples/Examples/Declarative-Map.swift) sample app.
19+
Set `NavigationMapView.useLegacyManualLayersOrderApproach` to `true` to enable legacy manual layer order calculation.
20+
1021
### Pricing
1122

1223
* Fixed a case when the SDK didn't respect `startLegIndex` when checking the waypoints for billing session for multiwaypoint routes. The SDK now correctly supports resuming a previous active guidance billing session when `startLegIndex` is greater than 0.

Examples/AdditionalExamples/Examples/Declarative-Map.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import Combine
88
import MapboxDirections
99
import MapboxMaps
10-
@_spi(ExperimentalMapboxAPI) import MapboxNavigationCore
10+
import MapboxNavigationCore
1111
import MapboxNavigationUIKit
1212
import UIKit
1313

@@ -39,7 +39,7 @@ final class DeclarativeMapViewController: UIViewController {
3939

4040
private var navigationContent: NavigationStyleContent? {
4141
didSet {
42-
// you need to call `setMapStyleContent()` for each NavigationStyleContent update
42+
// you need to call `setMapStyleContent(content:)` for each NavigationStyleContent update
4343
updateMapContent()
4444
}
4545
}
@@ -197,8 +197,11 @@ extension DeclarativeMapViewController {
197197
predictiveCacheManager: mapboxNavigationProvider.predictiveCacheManager
198198
)
199199
navigationMapView.mapView.mapboxMap.loadStyle(StyleURI(rawValue: Self.styleUrl)!)
200+
// The SDK won't call the `setMapStyleContent(content:)` now. You need to do it manually.
200201
navigationMapView.automaticallySetDeclarativeMapContent = false
201-
navigationMapView.useLegacyManualLayersOrderApproach = false
202+
203+
// Uncomment this line to use the legacy manual layers order approach.
204+
// navigationMapView.useLegacyManualLayersOrderApproach = true
202205

203206
navigationMapView.navigationStyleContent
204207
.sink { [weak self] navigationContent in

Sources/MapboxNavigationCore/Map/NavigationMapView.swift

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ open class NavigationMapView: UIView {
3737
/// present on the map. Enabled by default.
3838
public internal(set) var mapViewTapGestureRecognizer: UITapGestureRecognizer!
3939

40-
/// Provides the possibility to return to the manual layer order approach.
40+
/// Provides the possibility to use the manual layer order calculation approach.
4141
/// This property is`true` by default. Change this value to test a new rendering approach.
4242
@_spi(ExperimentalMapboxAPI)
4343
public var useLegacyManualLayersOrderApproach: Bool {
@@ -48,7 +48,6 @@ open class NavigationMapView: UIView {
4848
/// The current navigation style content being used.
4949
/// Returns `nil` if the declarative map style is not used.
5050
/// Set ``NavigationMapView/useLegacyManualLayersOrderApproach`` to `false` in order to enable it.
51-
@_spi(ExperimentalMapboxAPI)
5251
public var currentNavigationStyleContent: NavigationStyleContent? {
5352
mapStyleManager.currentNavigationStyleContent
5453
}
@@ -59,7 +58,6 @@ open class NavigationMapView: UIView {
5958
/// This property is`true` by default.
6059
/// Set ``NavigationMapView/useLegacyManualLayersOrderApproach`` to `false` in order to enable the declarative
6160
/// styling approach.
62-
@_spi(ExperimentalMapboxAPI)
6361
public var automaticallySetDeclarativeMapContent: Bool {
6462
get { !mapStyleManager.automaticallySetDeclarativeMapContent }
6563
set { mapStyleManager.automaticallySetDeclarativeMapContent = newValue }
@@ -70,7 +68,6 @@ open class NavigationMapView: UIView {
7068
/// Subscribers can observe this publisher to be notified when the ``NavigationStyleContent`` changes.
7169
/// Set ``NavigationMapView/useLegacyManualLayersOrderApproach`` to `false` in order to enable the declarative
7270
/// styling approach.
73-
@_spi(ExperimentalMapboxAPI)
7471
public var navigationStyleContent: AnyPublisher<NavigationStyleContent?, Never> {
7572
mapStyleManager.navigationStyleContent
7673
}
@@ -84,20 +81,54 @@ open class NavigationMapView: UIView {
8481
/// - heading: A publisher that emits current user heading. Defaults to `nil.`
8582
/// - predictiveCacheManager: An instance of ``PredictiveCacheManager`` used to continuously cache upcoming map
8683
/// tiles.
87-
public init(
84+
public convenience init(
8885
location: AnyPublisher<CLLocation, Never>,
8986
routeProgress: AnyPublisher<RouteProgress?, Never>,
9087
navigationCameraType: NavigationCameraType = .mobile,
9188
heading: AnyPublisher<CLHeading, Never>? = nil,
9289
predictiveCacheManager: PredictiveCacheManager? = nil
90+
) {
91+
self.init(
92+
location: location,
93+
routeProgress: routeProgress,
94+
navigationCameraType: navigationCameraType,
95+
heading: heading,
96+
predictiveCacheManager: predictiveCacheManager,
97+
useLegacyManualLayersOrderApproach: false
98+
)
99+
}
100+
101+
/// Initializes ``NavigationMapView`` instance.
102+
/// - Parameters:
103+
/// - location: A publisher that emits current user location.
104+
/// - routeProgress: A publisher that emits route navigation progress.
105+
/// - navigationCameraType: The type of ``NavigationCamera``. Defaults to ``NavigationCameraType/mobile``.
106+
/// which is used for the current instance of ``NavigationMapView``.
107+
/// - heading: A publisher that emits current user heading. Defaults to `nil.`
108+
/// - predictiveCacheManager: An instance of ``PredictiveCacheManager`` used to continuously cache upcoming map
109+
/// tiles.
110+
/// - useLegacyManualLayersOrderApproach: Provides the possibility to use the manual layer order calculation
111+
/// approach.
112+
@_spi(ExperimentalMapboxAPI)
113+
public init(
114+
location: AnyPublisher<CLLocation, Never>,
115+
routeProgress: AnyPublisher<RouteProgress?, Never>,
116+
navigationCameraType: NavigationCameraType = .mobile,
117+
heading: AnyPublisher<CLHeading, Never>? = nil,
118+
predictiveCacheManager: PredictiveCacheManager? = nil,
119+
useLegacyManualLayersOrderApproach: Bool = false
93120
) {
94121
self.mapView = MapView(frame: Constants.initialMapRect).autoresizing()
95122
mapView.location.override(
96123
locationProvider: location.map { [Location(clLocation: $0)] }.eraseToSignal(),
97124
headingProvider: heading?.map { Heading(from: $0) }.eraseToSignal()
98125
)
99126

100-
self.mapStyleManager = .init(mapView: mapView, customRouteLineLayerPosition: customRouteLineLayerPosition)
127+
self.mapStyleManager = .init(
128+
mapView: mapView,
129+
customRouteLineLayerPosition: customRouteLineLayerPosition,
130+
shouldUseDeclarativeApproach: !useLegacyManualLayersOrderApproach
131+
)
101132
self.navigationCamera = NavigationCamera(
102133
mapView,
103134
location: location,
@@ -522,6 +553,7 @@ open class NavigationMapView: UIView {
522553
routeProgress: routeProgress,
523554
config: mapStyleConfig
524555
)
556+
mapStyleManager.mapStyleDeclarativeContentUpdate()
525557
}
526558

527559
// MARK: - Debug Viewport

Sources/MapboxNavigationCore/Map/Style/NavigationMapStyleManager.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ protocol NavigationMapStyleManagerDelegate: AnyObject {
6868
/// Manages all the sources/layers used in NavigationMap.
6969
@MainActor
7070
final class NavigationMapStyleManager {
71-
// TODO: remove after declarative Maps API is fully supported.
72-
var shouldUseDeclarativeApproach: Bool = false {
71+
var shouldUseDeclarativeApproach: Bool = true {
7372
didSet {
7473
guard shouldUseDeclarativeApproach else { return }
7574

@@ -138,8 +137,13 @@ final class NavigationMapStyleManager {
138137
private let routeAnnotationsFeaturesStore: MapFeaturesStore
139138
private let routeAlertsFeaturesStore: MapFeaturesStore
140139

141-
init(mapView: MapView, customRouteLineLayerPosition: LayerPosition?) {
140+
init(
141+
mapView: MapView,
142+
customRouteLineLayerPosition: LayerPosition?,
143+
shouldUseDeclarativeApproach: Bool
144+
) {
142145
self.mapView = mapView
146+
self.shouldUseDeclarativeApproach = shouldUseDeclarativeApproach
143147
self.layersOrder = Self.makeMapLayersOrder(
144148
with: mapView,
145149
customRouteLineLayerPosition: customRouteLineLayerPosition

Sources/MapboxNavigationCore/Map/Style/NavigationStyleContent.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ enum NavigationSlot {
55
}
66

77
/// The navigation declarative map style content.
8-
@_spi(ExperimentalMapboxAPI)
98
public struct NavigationStyleContent: MapStyleContent {
109
var routeLines: [FeatureIds.RouteLine: RouteLineStyleContent] = [:]
1110
var waypoints: WaypointsLineStyleContent?

Tests/MapboxNavigationPackageTests/RouteLineLayerPositionTests.swift

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,29 @@ class RouteLineLayerPositionTests: TestCase {
8080
congestionConfiguration: .default
8181
)
8282

83-
navigationMapView = NavigationMapView(
83+
navigationMapView = configuredNavigationMapView()
84+
mapboxMap = configuredMapboxMap()
85+
}
86+
87+
@MainActor
88+
private func configuredNavigationMapView(useLegacyManualLayersOrderApproach: Bool = false) -> NavigationMapView {
89+
let navigationMapView = NavigationMapView(
8490
location: locationPublisher.eraseToAnyPublisher(),
85-
routeProgress: routeProgressPublisher.eraseToAnyPublisher()
91+
routeProgress: routeProgressPublisher.eraseToAnyPublisher(),
92+
useLegacyManualLayersOrderApproach: useLegacyManualLayersOrderApproach
8693
)
8794
navigationMapView.frame = UIScreen.main.bounds
95+
return navigationMapView
96+
}
97+
98+
@MainActor
99+
private func configuredMapboxMap() -> MapboxMap? {
88100
guard let mapboxMap = navigationMapView.mapView.mapboxMap else {
89101
XCTFail("Should have non-nil mapboxMap")
90-
return
102+
return nil
91103
}
92104
try? mapboxMap.addLayer(SlotLayer(id: Slot.middle!.rawValue))
93-
self.mapboxMap = mapboxMap
105+
return mapboxMap
94106
}
95107

96108
var route: Route {
@@ -134,7 +146,11 @@ class RouteLineLayerPositionTests: TestCase {
134146

135147
@MainActor
136148
func configureRouteLineLayerPosition(useLegacyManualLayersOrderApproach: Bool) {
137-
navigationMapView.useLegacyManualLayersOrderApproach = useLegacyManualLayersOrderApproach
149+
navigationMapView = configuredNavigationMapView(
150+
useLegacyManualLayersOrderApproach: useLegacyManualLayersOrderApproach
151+
)
152+
mapboxMap = configuredMapboxMap()
153+
138154
loadJsonStyle(slot: nil)
139155
let mainRouteIdentifier = FeatureIds.RouteLine.main.main
140156
let mainRouteCasingIdentifier = FeatureIds.RouteLine.main.casing
@@ -222,18 +238,18 @@ class RouteLineLayerPositionTests: TestCase {
222238
roadTrafficLayer["id"]!,
223239
roadLabelLayer["id"]!,
224240
roadExitLayer["id"]!,
241+
poiLabelLayer["id"]!,
242+
poiLabelCircleLayer["id"]!,
243+
Slot.middle!.rawValue,
225244
routeIds.casing,
226245
routeIds.main,
246+
routeIds.restrictedArea,
227247
arrowIds.arrowStroke,
228248
arrowIds.arrow,
229249
arrowIds.arrowSymbolCasing,
230250
arrowIds.arrowSymbol,
231-
routeIds.restrictedArea,
232-
poiLabelLayer["id"]!,
233-
poiLabelCircleLayer["id"]!,
234-
waypointIds.innerCircle,
235-
Slot.middle!.rawValue,
236251
NavigationSlot.aboveBasemap.rawValue,
252+
waypointIds.innerCircle,
237253
]
238254
XCTAssertEqual(
239255
allLayerIds,
@@ -253,14 +269,14 @@ class RouteLineLayerPositionTests: TestCase {
253269
roadTrafficLayer["id"]!,
254270
roadLabelLayer["id"]!,
255271
roadExitLayer["id"]!,
256-
routeIds.casing,
257-
routeIds.main,
258272
poiLabelLayer["id"]!,
259273
poiLabelCircleLayer["id"]!,
260-
intersectionIds.layer,
261-
waypointIds.innerCircle,
262274
Slot.middle!.rawValue,
275+
routeIds.casing,
276+
routeIds.main,
263277
NavigationSlot.aboveBasemap.rawValue,
278+
intersectionIds.layer,
279+
waypointIds.innerCircle,
264280
]
265281
allLayerIds = mapboxMap.allLayerIdentifiers.map { $0.id }
266282
XCTAssertEqual(allLayerIds, expectedLayerSequence, "Failed to apply custom layer position for route line.")
@@ -301,14 +317,14 @@ class RouteLineLayerPositionTests: TestCase {
301317
roadLabelLayer["id"]!,
302318
roadExitLayer["id"]!,
303319
Slot.middle!.rawValue,
304-
NavigationSlot.aboveBasemap.rawValue,
305320
routeIds.casing,
306321
routeIds.main,
322+
routeIds.restrictedArea,
307323
arrowIds.arrowStroke,
308324
arrowIds.arrow,
309325
arrowIds.arrowSymbolCasing,
310326
arrowIds.arrowSymbol,
311-
routeIds.restrictedArea,
327+
NavigationSlot.aboveBasemap.rawValue,
312328
intersectionIds.layer,
313329
routeAlertIds.layer,
314330
waypointIds.innerCircle,
@@ -326,13 +342,13 @@ class RouteLineLayerPositionTests: TestCase {
326342
roadLabelLayer["id"]!,
327343
roadExitLayer["id"]!,
328344
Slot.middle!.rawValue,
329-
NavigationSlot.aboveBasemap.rawValue,
330345
routeIds.casing,
331346
routeIds.main,
332347
arrowIds.arrowStroke,
333348
arrowIds.arrow,
334349
arrowIds.arrowSymbolCasing,
335350
arrowIds.arrowSymbol,
351+
NavigationSlot.aboveBasemap.rawValue,
336352
intersectionIds.layer,
337353
routeAlertIds.layer,
338354
waypointIds.innerCircle,
@@ -423,20 +439,20 @@ class RouteLineLayerPositionTests: TestCase {
423439
circleMapLayer,
424440
roadLabelLayer["id"]!,
425441
roadExitLayer["id"]!,
442+
poiLabelLayer["id"]!,
443+
poiLabelCircleLayer["id"]!,
444+
Slot.middle!.rawValue,
426445
routeIds.casing,
427446
routeIds.main,
447+
routeIds.restrictedArea,
428448
arrowIds.arrowStroke,
429449
arrowIds.arrow,
430450
arrowIds.arrowSymbolCasing,
431451
arrowIds.arrowSymbol,
432-
routeIds.restrictedArea,
433-
poiLabelLayer["id"]!,
434-
poiLabelCircleLayer["id"]!,
452+
NavigationSlot.aboveBasemap.rawValue,
435453
intersectionIds.layer,
436454
routeAlertIds.layer,
437455
waypointIds.innerCircle,
438-
Slot.middle!.rawValue,
439-
NavigationSlot.aboveBasemap.rawValue,
440456
circleLabelLayer,
441457
]
442458
allLayerIds = mapboxMap.allLayerIdentifiers.map { $0.id }

0 commit comments

Comments
 (0)