Skip to content

Copy RouteOptions as its most specific type #3192

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 21, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -126,6 +126,8 @@
* Fixed an issue where traffic congestion segments along the route line blurred into each other when the map was zoomed in far enough. ([#3153](https://github.com/mapbox/mapbox-navigation-ios/pull/3153))
* Supported feedbacks during passive navigation. Set `PassiveLocationManager` as a data source for `NavigationEventsManager` and then use this class to create and send user feedbacks. `FeedbackViewController` provides drop-in feedback screen and can be used during both passive and active navigation. ([#3122](https://github.com/mapbox/mapbox-navigation-ios/pull/3122))
* `NavigationViewController.indexedRoute`, `NavigationService.indexedRoute` and `Router.indexedRoute` properties are readonly now. Use dedicated `Router.updateRoute(with:routeOptions:)` method to update the route. ([#3159](https://github.com/mapbox/mapbox-navigation-ios/pull/#3159))
* Fixed an issue where a subclass of `NavigationRouteOptions` would turn into an ordinary `RouteOptions` when rerouting the user. ([#3192](https://github.com/mapbox/mapbox-navigation-ios/pull/3192))
* Renamed `RouteOptions.without(waypoint:)` to `RouteOptions.without(_:)`. ([#3192](https://github.com/mapbox/mapbox-navigation-ios/pull/3192))

## v1.4.1

2 changes: 1 addition & 1 deletion Example/ViewController.swift
Original file line number Diff line number Diff line change
@@ -519,7 +519,7 @@ extension ViewController: NavigationMapViewDelegate {

func navigationMapView(_ mapView: NavigationMapView, didSelect waypoint: Waypoint) {
guard let responseOptions = response?.options, case let .route(routeOptions) = responseOptions else { return }
let modifiedOptions = routeOptions.without(waypoint: waypoint)
let modifiedOptions = routeOptions.without(waypoint)

presentWaypointRemovalAlert { _ in
self.requestRoute(with:modifiedOptions, success: self.defaultSuccess, failure: self.defaultFailure)
4 changes: 4 additions & 0 deletions MapboxNavigation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
@@ -329,6 +329,7 @@
DA5F450025F07DE200F573EC /* ElectronicHorizonOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5F44FF25F07DE200F573EC /* ElectronicHorizonOptions.swift */; };
DA66063023B32F99007832E5 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA66062F23B32F99007832E5 /* Array.swift */; };
DA754E1923AC56E5007E16B5 /* MBXAccountsLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = DA754E1723AC56E5007E16B5 /* MBXAccountsLoader.m */; };
DA7A97CF26A7613D001B6A9A /* RouteOptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7A97CE26A7613C001B6A9A /* RouteOptionsTests.swift */; };
DA85D5EF25DB4AA4008A2AD4 /* LaneViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA85D5EE25DB4AA3008A2AD4 /* LaneViewTests.swift */; };
DA8F3A7623B5D84900B56786 /* SpeedLimitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F3A7523B5D84900B56786 /* SpeedLimitView.swift */; };
DA8F3A7823B5DB7900B56786 /* SpeedLimitStyleKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F3A7723B5DB7900B56786 /* SpeedLimitStyleKit.swift */; };
@@ -864,6 +865,7 @@
DA6C925A24C60C92003A0AD6 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Navigation.strings; sourceTree = "<group>"; };
DA73F87820BF851B0067649B /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = de; path = Resources/de.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
DA754E1723AC56E5007E16B5 /* MBXAccountsLoader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MBXAccountsLoader.m; path = include/MBXAccountsLoader.m; sourceTree = "<group>"; };
DA7A97CE26A7613C001B6A9A /* RouteOptionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RouteOptionsTests.swift; sourceTree = "<group>"; };
DA8264871F2AADC200454B24 /* zh-Hant */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Navigation.strings"; sourceTree = "<group>"; };
DA85D5EE25DB4AA3008A2AD4 /* LaneViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaneViewTests.swift; sourceTree = "<group>"; };
DA8F3A7523B5D84900B56786 /* SpeedLimitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpeedLimitView.swift; sourceTree = "<group>"; };
@@ -1175,6 +1177,7 @@
children = (
3A163ADF249901C300D66A0D /* RouteStateTests.swift */,
11D1F8A12696EBD40053A93F /* Dictionary+Equality.swift */,
DA7A97CE26A7613C001B6A9A /* RouteOptionsTests.swift */,
);
path = Extensions;
sourceTree = "<group>";
@@ -2502,6 +2505,7 @@
C582BA2C2073E77E00647DAA /* StringTests.swift in Sources */,
B426FEF425FFD5DC001884C8 /* RouteControllerTests.swift in Sources */,
352762A4225B751A0015B632 /* OptionsTests.swift in Sources */,
DA7A97CF26A7613D001B6A9A /* RouteOptionsTests.swift in Sources */,
8DB7EF6A2176674800DA83A3 /* MapboxNavigationServiceSpec.swift in Sources */,
B426FF0525FFD679001884C8 /* SimulatedLocationManagerTests.swift in Sources */,
35EF782A212C324E001B4BB5 /* TunnelAuthorityTests.swift in Sources */,
5 changes: 4 additions & 1 deletion Sources/MapboxCoreNavigation/NavigationRouteOptions.swift
Original file line number Diff line number Diff line change
@@ -6,7 +6,10 @@ import MapboxDirections
A `NavigationRouteOptions` object specifies turn-by-turn-optimized criteria for results returned by the Mapbox Directions API.

`NavigationRouteOptions` is a subclass of `RouteOptions` that has been optimized for navigation. Pass an instance of this class into the `Directions.calculate(_:completionHandler:)` method.
- note: `NavigationRouteOptions` is designed to be used with the `Directions` and `NavigationDirections` classes for specifying routing criteria. To customize the user experience in a `NavigationViewController`, use the `NavigationOptions` class.

This class implements the `NSCopying` protocol by round-tripping the object through `JSONEncoder` and `JSONDecoder`. If you subclass `NavigationRouteOptions`, make sure any properties you add are accounted for in `Decodable(from:)` and `Encodable.encode(to:)`. If your subclass contains any customizations that cannot be represented in JSON, make sure the subclass overrides `NSCopying.copy(with:)` to persist those customizations.

`NavigationRouteOptions` is designed to be used with the `Directions` and `NavigationDirections` classes for specifying routing criteria. To customize the user experience in a `NavigationViewController`, use the `NavigationOptions` class.
*/
open class NavigationRouteOptions: RouteOptions, OptimizedForNavigation {
/**
8 changes: 4 additions & 4 deletions Sources/MapboxCoreNavigation/RouteOptions.swift
Original file line number Diff line number Diff line change
@@ -30,12 +30,12 @@ extension RouteOptions {
}

extension RouteOptions: NSCopying {
public func copy(with zone: NSZone? = nil) -> Any {
open func copy(with zone: NSZone? = nil) -> Any {
do {
let encodedOptions = try JSONEncoder().encode(self)
return try JSONDecoder().decode(RouteOptions.self, from: encodedOptions)
return try JSONDecoder().decode(type(of: self), from: encodedOptions)
} catch {
preconditionFailure("Unable to copy RouteOptions by round-tripping it through JSON")
preconditionFailure("Unable to copy \(type(of: self)) by round-tripping it through JSON: \(error)")
}
}

@@ -45,7 +45,7 @@ extension RouteOptions: NSCopying {
- parameter waypoint: the Waypoint to exclude.
- returns: a copy of self excluding the specified waypoint.
*/
public func without(waypoint: Waypoint) -> RouteOptions {
public func without(_ waypoint: Waypoint) -> RouteOptions {
let waypointsWithoutSpecified = waypoints.filter { $0 != waypoint }
let copy = self.copy() as! RouteOptions
copy.waypoints = waypointsWithoutSpecified
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import XCTest
import CoreLocation
import MapboxDirections
@testable import MapboxCoreNavigation

/**
A hypothetical set of options optimized for golf carts.

This class uses options that may or may not be supported by the actual Mapbox Directions API.
*/
class GolfCartRouteOptions: NavigationRouteOptions {
override var urlQueryItems: [URLQueryItem] {
let maximumSpeed = Measurement(value: 20, unit: UnitSpeed.milesPerHour) // maximum legal speed in Ohio
let hourFromNow = Date().addingTimeInterval(60 * 60) // an hour from now
let hourFromNowString = ISO8601DateFormatter.string(from: hourFromNow, timeZone: .current, formatOptions: .withInternetDateTime)
return super.urlQueryItems + [
URLQueryItem(name: "maxspeed", value: String(maximumSpeed.converted(to: .kilometersPerHour).value)),
URLQueryItem(name: "depart_at", value: hourFromNowString),
URLQueryItem(name: "passengers", value: "3"),
]
}
}

class RouteOptionsTests: XCTestCase {
func testCopying() {
let coordinates: [CLLocationCoordinate2D] = [
.init(latitude: 0, longitude: 0),
.init(latitude: 1, longitude: 1),
]
let options = GolfCartRouteOptions(coordinates: coordinates, profileIdentifier: .automobile)
let copy = options.copy() as? GolfCartRouteOptions
XCTAssertNotNil(copy)
XCTAssertTrue(copy?.urlQueryItems.contains(URLQueryItem(name: "passengers", value: "3")) ?? false)
}
}