diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..6a7b23a716d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "thirdparty/osrm-text-instructions"] + path = thirdparty/osrm-text-instructions + url = https://github.com/Project-OSRM/osrm-text-instructions.git diff --git a/Cartfile b/Cartfile index 0656997c8c6..12f332a2ef1 100644 --- a/Cartfile +++ b/Cartfile @@ -1,6 +1,6 @@ binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" ~> 4.3 binary "https://www.mapbox.com/ios-sdk/MapboxNavigationNative.json" ~> 3.2 -github "mapbox/MapboxDirections.swift" ~> 0.24 +github "mapbox/MapboxDirections.swift" ~> 0.24.1 github "mapbox/turf-swift" ~> 0.2 github "mapbox/mapbox-events-ios" ~> 0.6 github "ceeK/Solar" ~> 2.1.0 diff --git a/MapboxCoreNavigation.podspec b/MapboxCoreNavigation.podspec index 30496e44cbb..4aa9ff4a59d 100644 --- a/MapboxCoreNavigation.podspec +++ b/MapboxCoreNavigation.podspec @@ -41,7 +41,7 @@ Pod::Spec.new do |s| s.module_name = "MapboxCoreNavigation" s.dependency "MapboxNavigationNative", "~> 3.2.0" - s.dependency "MapboxDirections.swift", "~> 0.24.0" # Always pin to a patch release if pre-1.0 + s.dependency "MapboxDirections.swift", "~> 0.24.1" # Always pin to a patch release if pre-1.0 s.dependency "MapboxMobileEvents", "~> 0.6.0" # Always pin to a patch release if pre-1.0 s.dependency "Turf", "~> 0.2.0" # Always pin to a patch release if pre-1.0 diff --git a/MapboxCoreNavigation/MBRouteController.h b/MapboxCoreNavigation/MBRouteController.h index 5c8eec0a661..e332db6ced2 100644 --- a/MapboxCoreNavigation/MBRouteController.h +++ b/MapboxCoreNavigation/MBRouteController.h @@ -82,3 +82,4 @@ extern const MBRouteControllerNotificationUserInfoKey MBRouteControllerIsProacti @interface NSString (MD5) - (NSString * _Nonnull)md5; @end + diff --git a/MapboxCoreNavigation/MBRouteController.m b/MapboxCoreNavigation/MBRouteController.m index 6ed777c04ae..380f04cdf29 100644 --- a/MapboxCoreNavigation/MBRouteController.m +++ b/MapboxCoreNavigation/MBRouteController.m @@ -16,6 +16,7 @@ NSString *const MBErrorDomain = @"ErrorDomain"; + @implementation NSString (MD5) - (NSString * _Nonnull)md5 { const char *cStr = [self UTF8String]; @@ -30,3 +31,4 @@ - (NSString * _Nonnull)md5 { return output; } @end + diff --git a/MapboxCoreNavigation/OfflineDirections.swift b/MapboxCoreNavigation/OfflineDirections.swift new file mode 100644 index 00000000000..8a925fa838f --- /dev/null +++ b/MapboxCoreNavigation/OfflineDirections.swift @@ -0,0 +1,140 @@ +import Foundation +import MapboxDirections +import MapboxNavigationNative + +public typealias OfflineDirectionsCompletionHandler = (_ numberOfTiles: UInt64) -> Void + +enum OfflineRoutingError: Error, LocalizedError { + case unexpectedRouteResult(String) + case corruptRouteData(String) + case responseError(String) + + public var localizedDescription: String { + switch self { + case .corruptRouteData(let value): + return value + case .unexpectedRouteResult(let value): + return value + case .responseError(let value): + return value + } + } + + var errorDescription: String? { + return localizedDescription + } +} + +struct OfflineDirectionsConstants { + static let offlineSerialQueueLabel = Bundle.mapboxCoreNavigation.bundleIdentifier!.appending(".offline") + static let serialQueue = DispatchQueue(label: OfflineDirectionsConstants.offlineSerialQueueLabel) +} + +/** + Defines additional functionality similar to `Directions` with support for offline routing. + */ +@objc(MBOfflineDirectionsProtocol) +public protocol OfflineRoutingProtocol { + + /** + Initializes a newly created directions object with an optional access token and host. + + - parameter tilesPath: The location where the tiles has been sideloaded to. + - parameter translationsPath: The location where the translations has been sideloaded to. + - parameter accessToken: A Mapbox [access token](https://www.mapbox.com/help/define-access-token/). If an access token is not specified when initializing the directions object, it should be specified in the `MGLMapboxAccessToken` key in the main application bundle’s Info.plist. + - parameter host: An optional hostname to the server API. The [Mapbox Directions API](https://www.mapbox.com/api-documentation/?language=Swift#directions) endpoint is used by default. + */ + init(tilesURL: URL, translationsURL: URL, accessToken: String?, host: String?, completionHandler: @escaping OfflineDirectionsCompletionHandler) + + /** + Begins asynchronously calculating the route or routes using the given options and delivers the results to a closure. + + This method retrieves the routes asynchronously via MapboxNavigationNative. + + Routes may be displayed atop a [Mapbox map](https://www.mapbox.com/maps/). They may be cached but may not be stored permanently. To use the results in other contexts or store them permanently, [upgrade to a Mapbox enterprise plan](https://www.mapbox.com/directions/#pricing). + + - parameter options: A `RouteOptions` object specifying the requirements for the resulting routes. + - parameter completionHandler: The closure (block) to call with the resulting routes. This closure is executed on the application’s main thread. + */ + func calculate(_ options: RouteOptions, offline: Bool, completionHandler: @escaping Directions.RouteCompletionHandler) +} + +@objc(MBNavigationDirections) +public class NavigationDirections: Directions, OfflineRoutingProtocol { + + public required init(tilesURL: URL, translationsURL: URL, accessToken: String?, host: String? = nil, completionHandler: @escaping OfflineDirectionsCompletionHandler) { + + super.init(accessToken: accessToken, host: host) + + OfflineDirectionsConstants.serialQueue.sync { + let tilesPath = tilesURL.absoluteString.replacingOccurrences(of: "file://", with: "") + let translationsPath = translationsURL.absoluteString.replacingOccurrences(of: "file://", with: "") + let tileCount = self.navigator.configureRouter(forTilesPath: tilesPath, translationsPath: translationsPath) + + DispatchQueue.main.async { + completionHandler(tileCount) + } + } + } + + public func calculate(_ options: RouteOptions, offline: Bool = false, completionHandler: @escaping Directions.RouteCompletionHandler) { + + guard offline == true else { + return calculate(options, completionHandler: completionHandler) + } + + let url = self.url(forCalculating: options) + + OfflineDirectionsConstants.serialQueue.sync { [weak self] in + + guard let result = self?.navigator.getRouteForDirectionsUri(url.absoluteString) else { + let error = OfflineRoutingError.unexpectedRouteResult("Unexpected routing result") + return completionHandler(nil, nil, error as NSError) + } + + guard let data = result.json.data(using: .utf8) else { + let error = OfflineRoutingError.corruptRouteData("Corrupt route data") + return completionHandler(nil, nil, error as NSError) + } + + do { + let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any] + if let errorValue = json["error"] as? String { + DispatchQueue.main.async { + let error = OfflineRoutingError.responseError(errorValue) + return completionHandler(nil, nil, error as NSError) + } + } else { + let response = options.response(from: json) + + DispatchQueue.main.async { + return completionHandler(response.0, response.1, nil) + } + } + + } catch { + DispatchQueue.main.async { + return completionHandler(nil, nil, error as NSError) + } + } + } + } + + var _navigator: MBNavigator! + var navigator: MBNavigator { + + assert(currentQueueName() == OfflineDirectionsConstants.offlineSerialQueueLabel, + "The offline navigator must be accessed from the dedicated serial queue") + + if _navigator == nil { + self._navigator = MBNavigator() + } + + return _navigator + } +} + +fileprivate func currentQueueName() -> String? { + let name = __dispatch_queue_get_label(nil) + return String(cString: name, encoding: .utf8) +} diff --git a/MapboxCoreNavigationTests/CocoaPodsTest/PodInstall/Podfile.lock b/MapboxCoreNavigationTests/CocoaPodsTest/PodInstall/Podfile.lock index 5126d9abf5b..cd281e3bb19 100644 --- a/MapboxCoreNavigationTests/CocoaPodsTest/PodInstall/Podfile.lock +++ b/MapboxCoreNavigationTests/CocoaPodsTest/PodInstall/Podfile.lock @@ -1,7 +1,7 @@ PODS: - Mapbox-iOS-SDK (4.5.0) - MapboxCoreNavigation (0.23.0): - - MapboxDirections.swift (~> 0.24.0) + - MapboxDirections.swift (~> 0.24.1) - MapboxMobileEvents (~> 0.6.0) - MapboxNavigationNative (~> 3.2.0) - Turf (~> 0.2.0) diff --git a/MapboxCoreNavigationTests/dc-line.geojson b/MapboxCoreNavigationTests/Fixtures/dc-line.geojson similarity index 100% rename from MapboxCoreNavigationTests/dc-line.geojson rename to MapboxCoreNavigationTests/Fixtures/dc-line.geojson diff --git a/MapboxCoreNavigationTests/md5_crazy_strings.txt b/MapboxCoreNavigationTests/Fixtures/md5_crazy_strings.txt similarity index 100% rename from MapboxCoreNavigationTests/md5_crazy_strings.txt rename to MapboxCoreNavigationTests/Fixtures/md5_crazy_strings.txt diff --git a/MapboxCoreNavigationTests/route.json b/MapboxCoreNavigationTests/Fixtures/route.json similarity index 100% rename from MapboxCoreNavigationTests/route.json rename to MapboxCoreNavigationTests/Fixtures/route.json diff --git a/MapboxCoreNavigationTests/routeWithInstructions.json b/MapboxCoreNavigationTests/Fixtures/routeWithInstructions.json similarity index 100% rename from MapboxCoreNavigationTests/routeWithInstructions.json rename to MapboxCoreNavigationTests/Fixtures/routeWithInstructions.json diff --git a/MapboxCoreNavigationTests/routeWithTunnels_9thStreetDC.json b/MapboxCoreNavigationTests/Fixtures/routeWithTunnels_9thStreetDC.json similarity index 100% rename from MapboxCoreNavigationTests/routeWithTunnels_9thStreetDC.json rename to MapboxCoreNavigationTests/Fixtures/routeWithTunnels_9thStreetDC.json diff --git a/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/0/003/107.gph.gz b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/0/003/107.gph.gz new file mode 100644 index 00000000000..f0018734ad6 Binary files /dev/null and b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/0/003/107.gph.gz differ diff --git a/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/1/049/509.gph.gz b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/1/049/509.gph.gz new file mode 100644 index 00000000000..38d47e33442 Binary files /dev/null and b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/1/049/509.gph.gz differ diff --git a/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/2/000/789/877.gph.gz b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/2/000/789/877.gph.gz new file mode 100644 index 00000000000..862c4864bd9 Binary files /dev/null and b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/2/000/789/877.gph.gz differ diff --git a/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/2/000/789/878.gph.gz b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/2/000/789/878.gph.gz new file mode 100644 index 00000000000..a878022b17b Binary files /dev/null and b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/2/000/789/878.gph.gz differ diff --git a/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/2/000/791/318.gph.gz b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/2/000/791/318.gph.gz new file mode 100644 index 00000000000..3a44e844732 Binary files /dev/null and b/MapboxCoreNavigationTests/Fixtures/routing/liechtenstein/2/000/791/318.gph.gz differ diff --git a/MapboxCoreNavigationTests/straight-line.json b/MapboxCoreNavigationTests/Fixtures/straight-line.json similarity index 100% rename from MapboxCoreNavigationTests/straight-line.json rename to MapboxCoreNavigationTests/Fixtures/straight-line.json diff --git a/MapboxCoreNavigationTests/tunnel.json b/MapboxCoreNavigationTests/Fixtures/tunnel.json similarity index 100% rename from MapboxCoreNavigationTests/tunnel.json rename to MapboxCoreNavigationTests/Fixtures/tunnel.json diff --git a/MapboxCoreNavigationTests/tunnel.route b/MapboxCoreNavigationTests/Fixtures/tunnel.route similarity index 100% rename from MapboxCoreNavigationTests/tunnel.route rename to MapboxCoreNavigationTests/Fixtures/tunnel.route diff --git a/MapboxCoreNavigationTests/OfflineRoutingTests.swift b/MapboxCoreNavigationTests/OfflineRoutingTests.swift new file mode 100644 index 00000000000..f7a28118cb7 --- /dev/null +++ b/MapboxCoreNavigationTests/OfflineRoutingTests.swift @@ -0,0 +1,75 @@ +import XCTest +import MapboxDirections +@testable import MapboxCoreNavigation + + +class OfflineRoutingTests: XCTestCase { + + func testOfflineDirections() { + let bundle = Bundle(for: OfflineRoutingTests.self) + let tilesURL = URL(fileURLWithPath: bundle.bundlePath.appending("/routing/liechtenstein")) + let translationsURL = URL(fileURLWithPath: bundle.bundlePath.appending("/translations")) + + let setupExpectation = expectation(description: "Set up offline routing") + + let directions = NavigationDirections(tilesURL: tilesURL, translationsURL: translationsURL, accessToken: "foo") { (numberOfTiles) in + XCTAssertEqual(numberOfTiles, 5) + setupExpectation.fulfill() + } + + wait(for: [setupExpectation], timeout: 2) + + // Coordinates within Liechtenstein + let coordinates = [CLLocationCoordinate2D(latitude: 47.1192, longitude: 9.5412), + CLLocationCoordinate2D(latitude: 47.1153, longitude: 9.5531)] + + let options = NavigationRouteOptions(coordinates: coordinates, profileIdentifier: .automobile) + let calculateRouteExpectation = expectation(description: "Calculate route offline") + var route: Route? + + directions.calculate(options, offline: true) { (waypoints, routes, error) in + XCTAssertNil(error) + XCTAssertNotNil(waypoints) + XCTAssertNotNil(routes) + route = routes!.first! + calculateRouteExpectation.fulfill() + } + + wait(for: [calculateRouteExpectation], timeout: 2) + + XCTAssertNotNil(route) + XCTAssertEqual(route!.coordinates!.count, 239) + } + + func testOfflineDirectionsError() { + let bundle = Bundle(for: OfflineRoutingTests.self) + let tilesURL = URL(fileURLWithPath: bundle.bundlePath).appendingPathComponent("/routing/liechtenstein") + let translationsURL = URL(fileURLWithPath: bundle.bundlePath).appendingPathComponent("/translations") + + let setupExpectation = expectation(description: "Set up offline routing") + + let directions = NavigationDirections(tilesURL: tilesURL, translationsURL: translationsURL, accessToken: "foo") { (numberOfTiles) in + XCTAssertEqual(numberOfTiles, 5) + setupExpectation.fulfill() + } + + wait(for: [setupExpectation], timeout: 2) + + // Coordinates in SF + let coordinates = [CLLocationCoordinate2D(latitude: 37.7870, longitude: -122.4261), + CLLocationCoordinate2D(latitude: 37.7805, longitude: -122.4073)] + + let options = NavigationRouteOptions(coordinates: coordinates, profileIdentifier: .automobile) + let calculateRouteExpectation = expectation(description: "Calculate route offline") + + directions.calculate(options, offline: true) { (waypoints, routes, error) in + XCTAssertNotNil(error) + XCTAssertEqual(error!.localizedDescription, "No suitable edges near location") + XCTAssertNil(routes) + XCTAssertNil(waypoints) + calculateRouteExpectation.fulfill() + } + + wait(for: [calculateRouteExpectation], timeout: 2) + } +} diff --git a/MapboxNavigation.xcodeproj/project.pbxproj b/MapboxNavigation.xcodeproj/project.pbxproj index 2664ff1fd22..7f11e70a555 100644 --- a/MapboxNavigation.xcodeproj/project.pbxproj +++ b/MapboxNavigation.xcodeproj/project.pbxproj @@ -41,6 +41,7 @@ 35002D761E5F6CD30090E733 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 35002D741E5F6CD30090E733 /* Main.storyboard */; }; 3502231A205BC94E00E1449A /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35022319205BC94E00E1449A /* Constants.swift */; }; 35025F3F1F051DD2002BA3EA /* DialogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35025F3E1F051DD2002BA3EA /* DialogViewController.swift */; }; + 3506DE3A216E2ADE007DA352 /* OfflineRoutingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3506DE39216E2ADE007DA352 /* OfflineRoutingTests.swift */; }; 3507F9FB2134309E0086B39E /* MapboxGeocoder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3507F9F92134305C0086B39E /* MapboxGeocoder.framework */; }; 3507F9FC2134309E0086B39E /* MapboxGeocoder.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3507F9F92134305C0086B39E /* MapboxGeocoder.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 3510300F1F54B67000E3B7E7 /* LaneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3510300E1F54B67000E3B7E7 /* LaneTests.swift */; }; @@ -193,11 +194,13 @@ 35D457A71E2D253100A89946 /* MBRouteController.h in Headers */ = {isa = PBXBuildFile; fileRef = 35D457A61E2D253100A89946 /* MBRouteController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 35D825FC1E6A2DBE0088F83B /* MGLMapView+MGLNavigationAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 35D825FA1E6A2DBE0088F83B /* MGLMapView+MGLNavigationAdditions.m */; }; 35D825FE1E6A2EC60088F83B /* MapboxNavigation.h in Headers */ = {isa = PBXBuildFile; fileRef = 35D825FD1E6A2EC60088F83B /* MapboxNavigation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 35D92FF421825604000C78CB /* translations in Resources */ = {isa = PBXBuildFile; fileRef = 35D92FF321825603000C78CB /* translations */; }; 35DA85791FC45787004092EC /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35DA85781FC45787004092EC /* StatusView.swift */; }; 35DC585D1FABC61100B5A956 /* InstructionsBannerViewIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35DC585C1FABC61100B5A956 /* InstructionsBannerViewIntegrationTests.swift */; }; 35DC9D8D1F431E59001ECD64 /* route.json in Resources */ = {isa = PBXBuildFile; fileRef = C52D09CD1DEF5E5100BE3C5C /* route.json */; }; 35DC9D8F1F4321CC001ECD64 /* route-with-lanes.json in Resources */ = {isa = PBXBuildFile; fileRef = 35DC9D8E1F4321CC001ECD64 /* route-with-lanes.json */; }; 35DC9D911F4323AA001ECD64 /* LanesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35DC9D901F4323AA001ECD64 /* LanesView.swift */; }; + 35E102662166360300A07109 /* OfflineDirections.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35E102652166360300A07109 /* OfflineDirections.swift */; }; 35E407681F5625FF00EFC814 /* StyleKitMarker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35E407671F5625FF00EFC814 /* StyleKitMarker.swift */; }; 35E9B0AD1F9E0F8F00BF84AB /* MapboxNavigation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 351BEBD71E5BCC28006FE110 /* MapboxNavigation.framework */; }; 35EB9A6A20A1AB7C00CB1225 /* turn_left.data in Resources */ = {isa = PBXBuildFile; fileRef = 35EB9A6920A1A89500CB1225 /* turn_left.data */; }; @@ -207,6 +210,7 @@ 35F1F5931FD57EFD00F8E502 /* StyleManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F1F5921FD57EFD00F8E502 /* StyleManagerTests.swift */; }; 35F520C01FB482A200FC9C37 /* NextBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F520BF1FB482A200FC9C37 /* NextBannerView.swift */; }; 35F611C41F1E1C0500C43249 /* FeedbackViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F611C31F1E1C0500C43249 /* FeedbackViewController.swift */; }; + 35F70606217496A60065244B /* routing in Resources */ = {isa = PBXBuildFile; fileRef = 35F70605217496A60065244B /* routing */; }; 3EA9301B03F8679BEDD4795F /* Cache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA93A10227A7DAF1861D9F5 /* Cache.swift */; }; 3EA932D8F44915EFF3B8A088 /* SpeechAPISpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA93170CB959F3065ACFFC3 /* SpeechAPISpy.swift */; }; 3EA9369C33A8F10DAE9043AA /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA934C5D8DBAA19DB0F5271 /* ImageDownloader.swift */; }; @@ -585,6 +589,7 @@ 35002D751E5F6CD30090E733 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 35022319205BC94E00E1449A /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; 35025F3E1F051DD2002BA3EA /* DialogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DialogViewController.swift; sourceTree = ""; }; + 3506DE39216E2ADE007DA352 /* OfflineRoutingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfflineRoutingTests.swift; sourceTree = ""; }; 3507F9F92134305C0086B39E /* MapboxGeocoder.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapboxGeocoder.framework; path = Carthage/Build/iOS/MapboxGeocoder.framework; sourceTree = ""; }; 3510300E1F54B67000E3B7E7 /* LaneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaneTests.swift; sourceTree = ""; }; 351030101F54B72000E3B7E7 /* route-for-lane-testing.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "route-for-lane-testing.json"; sourceTree = ""; }; @@ -726,16 +731,19 @@ 35D825F91E6A2DBE0088F83B /* MGLMapView+MGLNavigationAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLMapView+MGLNavigationAdditions.h"; sourceTree = ""; }; 35D825FA1E6A2DBE0088F83B /* MGLMapView+MGLNavigationAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLMapView+MGLNavigationAdditions.m"; sourceTree = ""; }; 35D825FD1E6A2EC60088F83B /* MapboxNavigation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapboxNavigation.h; sourceTree = ""; }; + 35D92FF321825603000C78CB /* translations */ = {isa = PBXFileReference; lastKnownFileType = folder; name = translations; path = "thirdparty/osrm-text-instructions/languages/translations"; sourceTree = SOURCE_ROOT; }; 35DA85781FC45787004092EC /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = ""; }; 35DC585C1FABC61100B5A956 /* InstructionsBannerViewIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstructionsBannerViewIntegrationTests.swift; sourceTree = ""; }; 35DC9D8E1F4321CC001ECD64 /* route-with-lanes.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "route-with-lanes.json"; sourceTree = ""; }; 35DC9D901F4323AA001ECD64 /* LanesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanesView.swift; sourceTree = ""; }; + 35E102652166360300A07109 /* OfflineDirections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfflineDirections.swift; sourceTree = ""; }; 35E407671F5625FF00EFC814 /* StyleKitMarker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyleKitMarker.swift; sourceTree = ""; }; 35EB9A6920A1A89500CB1225 /* turn_left.data */ = {isa = PBXFileReference; lastKnownFileType = file; path = turn_left.data; sourceTree = ""; }; 35ECAF2C2092275100DC3BC3 /* UIImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImage.swift; sourceTree = ""; }; 35F1F5921FD57EFD00F8E502 /* StyleManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyleManagerTests.swift; sourceTree = ""; }; 35F520BF1FB482A200FC9C37 /* NextBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextBannerView.swift; sourceTree = ""; }; 35F611C31F1E1C0500C43249 /* FeedbackViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbackViewController.swift; sourceTree = ""; }; + 35F70605217496A60065244B /* routing */ = {isa = PBXFileReference; lastKnownFileType = folder; path = routing; sourceTree = ""; }; 3EA93170CB959F3065ACFFC3 /* SpeechAPISpy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpeechAPISpy.swift; sourceTree = ""; }; 3EA93230997B8D59E3B76C8C /* InstructionPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstructionPresenter.swift; sourceTree = ""; }; 3EA934C5D8DBAA19DB0F5271 /* ImageDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageDownloader.swift; sourceTree = ""; }; @@ -1453,6 +1461,8 @@ C52D09CF1DEF5E5F00BE3C5C /* Fixtures */ = { isa = PBXGroup; children = ( + 35D92FF321825603000C78CB /* translations */, + 35F70605217496A60065244B /* routing */, 35718BE41EF316BA00AFA3D1 /* tunnel.json */, 35718BE31EF316BA00AFA3D1 /* tunnel.route */, C52D09CD1DEF5E5100BE3C5C /* route.json */, @@ -1462,7 +1472,7 @@ AEF2C8F12072B603007B061F /* routeWithTunnels_9thStreetDC.json */, C5A60ECA20A241B600C21178 /* md5_crazy_strings.txt */, ); - name = Fixtures; + path = Fixtures; sourceTree = ""; }; C53C196A1F38E9C1008DB406 /* Resources */ = { @@ -1556,6 +1566,7 @@ 3582A24F20EEC46B0029C5DE /* Router.swift */, 353E69031EF0C4E5007B2AE5 /* SimulatedLocationManager.swift */, 35C98730212E02B500808B82 /* PortableRouteController.swift */, + 35E102652166360300A07109 /* OfflineDirections.swift */, ); path = MapboxCoreNavigation; sourceTree = ""; @@ -1581,6 +1592,7 @@ C52AC1251DF0E48600396B9F /* RouteProgressTests.swift */, C582BA2B2073E77E00647DAA /* StringTests.swift */, AE8B1B96207D2B2B003050F6 /* TunnelAuthorityTests.swift */, + 3506DE39216E2ADE007DA352 /* OfflineRoutingTests.swift */, ); path = MapboxCoreNavigationTests; sourceTree = ""; @@ -2044,6 +2056,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 35F70606217496A60065244B /* routing in Resources */, C5387A9D1F8FDB13000D2E93 /* routeWithInstructions.json in Resources */, C5EF397520599120009A2C50 /* straight-line.json in Resources */, C5A60ECD20A25DA100C21178 /* md5_crazy_strings.txt in Resources */, @@ -2051,6 +2064,7 @@ AEF2C8F22072B603007B061F /* routeWithTunnels_9thStreetDC.json in Resources */, 35718BE71EF3194200AFA3D1 /* tunnel.json in Resources */, C52D09CE1DEF5E5100BE3C5C /* route.json in Resources */, + 35D92FF421825604000C78CB /* translations in Resources */, 35718BE81EF3194500AFA3D1 /* tunnel.route in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2368,6 +2382,7 @@ C5381F02204E03B600A5493E /* UIDevice.swift in Sources */, 354A9BCB20EA9BDA00F03325 /* EventDetails.swift in Sources */, 8D1A5CD2212DDFCD0059BA4A /* CountdownTimer.swift in Sources */, + 35E102662166360300A07109 /* OfflineDirections.swift in Sources */, C561735B1F182113005954F6 /* RouteStep.swift in Sources */, 354A9BC620EA991900F03325 /* SessionState.swift in Sources */, 35C98733212E037900808B82 /* MBFixLocation.swift in Sources */, @@ -2415,6 +2430,7 @@ 16435E05206EE37800AF48B6 /* DummyURLSessionDataTask.swift in Sources */, 8DB7EF6C2176688D00DA83A3 /* LeakTest.swift in Sources */, C5ADFBD81DDCC7840011824B /* MapboxCoreNavigationTests.swift in Sources */, + 3506DE3A216E2ADE007DA352 /* OfflineRoutingTests.swift in Sources */, 16120A4D20645D6E007EA21D /* NavigationEventsManagerTestDoubles.swift in Sources */, C551B0E620D42222009A986F /* NavigationLocationManagerTests.swift in Sources */, 359A8AED1FA78D3000BDB486 /* DistanceFormatterTests.swift in Sources */, diff --git a/MapboxNavigation.xcodeproj/xcshareddata/xcschemes/MapboxCoreNavigation.xcscheme b/MapboxNavigation.xcodeproj/xcshareddata/xcschemes/MapboxCoreNavigation.xcscheme index 64f4ecb65dc..3b79bba3881 100644 --- a/MapboxNavigation.xcodeproj/xcshareddata/xcschemes/MapboxCoreNavigation.xcscheme +++ b/MapboxNavigation.xcodeproj/xcshareddata/xcschemes/MapboxCoreNavigation.xcscheme @@ -41,6 +41,9 @@ + + diff --git a/circle.yml b/circle.yml index ef057b2eaa9..ee2a86777a6 100644 --- a/circle.yml +++ b/circle.yml @@ -51,6 +51,7 @@ step-library: name: Prepare command: | git submodule sync + git submodule update --init --recursive if (brew outdated | grep carthage > /dev/null); then brew upgrade carthage; fi echo "foo" > ~/.mapbox diff --git a/thirdparty/osrm-text-instructions b/thirdparty/osrm-text-instructions new file mode 160000 index 00000000000..ebd6c236054 --- /dev/null +++ b/thirdparty/osrm-text-instructions @@ -0,0 +1 @@ +Subproject commit ebd6c236054bf3d852dcefea23cd3d376da66560