Skip to content
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

Offline routing #1768

Merged
merged 22 commits into from
Oct 29, 2018
Merged

Offline routing #1768

merged 22 commits into from
Oct 29, 2018

Conversation

frederoni
Copy link
Contributor

@frederoni frederoni commented Oct 8, 2018

Note: this PR targets the offline-routing branch.

Started outlining offline routing.

This PR

  • Support for Offline Routing via MapboxOfflineDirections
  • Release v0.24.1 of MapboxDirections.swift with support for deserializing routes from external sources (fixes the remaining CI 🔴)
  • Release a new version of MapboxNavigationNative

Subsequent PR

  • Mimic a URLSessionDataTask for Directions.calculateOffline to allow canceling a request and make it easier to combine and use fallbacks between online and offline directions.
  • UI for downloading a region

cc @akitchen @JThramer

Cartfile Outdated
@@ -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.1
github "mapbox/MapboxDirections.swift" ~> 0.24
github "mapbox/MapboxDirections.swift" "fred/public-result"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make a new release of MapboxDirections.swift


var _navigator: MBNavigator!
var navigator: MBNavigator {
//assert(OperationQueue.current?.underlyingQueue?.label == ExtendedDirections.offlineSerialQueueLabel,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix this assertion

// 1: uncompressed tiles packed in a tar archive,
// 2: uncompressed tiles in directories
// 3: compressed tiles in directories
// We are using the 3rd option
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we capture these exceptions? If so, I think we would have to capture them in Obj-C.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that's the case, do we need the OfflineDirections class to be written in ObjC? Or another intermediary wrapper perhaps? Obviously we can't have these exceptions (which seem like they could be used for control flow or cascading workflow options) to crash the containing app.


public typealias RouteCompletionHandler = (_ waypoints: [Waypoint]?, _ routes: [Route]?, _ error: NSError?) -> Void

public class ExtendedDirections: NSObject {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OfflineDirections might be a better name. Perhaps the functionality could be added as an extension on the existing Directions object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if OfflineDirections and Directions both conformed to a DirectionsProtocol protocol (although we'd still need to figure out naming).


switch navigationOptions.preferredRequestOption {
case .preferClientSide:
fatalError("Not yet implemented")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to wonder - does this option deserve to exist? when would we prefer client side but still "fall back" to server-generated directions? lack of tiles?

case .preferClientSide:
fatalError("Not yet implemented")
case .preferServerSide:
fatalError("Not yet implemented")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the thinking here - preflighting an HTTP request is discouraged/considered an anti-pattern these days

@frederoni frederoni force-pushed the fred/offline-routing branch 5 times, most recently from 103d8b0 to 36f13c1 Compare October 16, 2018 13:56
@akitchen akitchen requested a review from 1ec5 October 23, 2018 22:40
@frederoni frederoni changed the base branch from master to offline-routing October 25, 2018 11:19
@@ -82,3 +83,9 @@ extern const MBRouteControllerNotificationUserInfoKey MBRouteControllerIsProacti
@interface NSString (MD5)
- (NSString * _Nonnull)md5;
@end

@interface MBNavigator (additions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: category names should be in camel case just like class names. A conventional category name would be MBCoreNavigationAdditions (since both MapboxNavigationNative and MapboxCoreNavigation use the same class prefix).


@interface MBNavigator (additions)

- (NSUInteger)setupRouter:(NSString *)tilesPath translationsPath:(NSString *)translationsPath;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: “set up” here is being used as a verb, so it should be setUpRouter:.

static let serialQueue = DispatchQueue(label: OfflineDirectionsConstants.offlineSerialQueueLabel)
}

@objc(MBOfflineDirectionsProtocol)

This comment was marked as resolved.


public typealias OfflineDirectionsCompletionHandler = (_ numberOfTiles: UInt) -> Void

public enum OfflineRoutingError: Error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this enumeration bridge to Objective-C? If so, it needs a class prefix in Objective-C (and documentation).

Copy link
Contributor Author

@frederoni frederoni Oct 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These errors are casted to NSErrors but I guess it needs a localized description key? Or does Error bridge fine to Obj-C since Swift 4.0? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, yeah, the localized description keys would need to be provided somehow, though I’m not sure exactly how that works when relying on bridging from Error in Swift.

- parameter tilesPath: The location where the tiles has been sideloaded to.
- parameter translationsPath: The location where the translations has been sideloaded to.
*/
init(accessToken: String?, host: String?, tilesPath: String, translationsPath: String, completionHandler: @escaping OfflineDirectionsCompletionHandler)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s a bit odd that optional arguments come before required arguments. Can tilesPath and translationsPath come first?

@@ -0,0 +1 @@
{"meta":{"capitalizeFirstLetter":false},"v5":{"constants":{"ordinalize":{"1":"第一","2":"第二","3":"第三","4":"第四","5":"第五","6":"第六","7":"第七","8":"第八","9":"第九","10":"第十"},"direction":{"north":"北","northeast":"东北","east":"东","southeast":"东南","south":"南","southwest":"西南","west":"西","northwest":"西北"},"modifier":{"left":"向左","right":"向右","sharp left":"急向左","sharp right":"急向右","slight left":"稍向左","slight right":"稍向右","straight":"直行","uturn":"调头"},"lanes":{"xo":"靠右行驶","ox":"靠左行驶","xox":"保持在道路中间行驶","oxo":"保持在道路左侧或右侧行驶"}},"modes":{"ferry":{"default":"乘坐轮渡","name":"乘坐{way_name}轮渡","destination":"乘坐开往{destination}的轮渡"}},"phrase":{"two linked by distance":"{instruction_one},{distance}后{instruction_two}","two linked":"{instruction_one},随后{instruction_two}","one in distance":"{distance}后{instruction_one}","name and ref":"{name}({ref})","exit with number":"出口{exit}"},"arrive":{"default":{"default":"您已经到达您的{nth}个目的地","upcoming":"您即将到达您的{nth}个目的地","short":"已到达目的地","short-upcoming":"即将到达目的地","named":"您已到达{waypoint_name}"},"left":{"default":"您已经到达您的{nth}个目的地,目的地在道路左侧","upcoming":"您即将到达您的{nth}个目的地,目的地在道路左侧","short":"已到达目的地","short-upcoming":"即将到达目的地","named":"您已到达{waypoint_name},目的地在您左边。"},"right":{"default":"您已经到达您的{nth}个目的地,目的地在道路右侧","upcoming":"您即将到达您的{nth}个目的地,目的地在道路右侧","short":"已到达目的地","short-upcoming":"即将到达目的地","named":"您已到达{waypoint_name},目的地在您右边。"},"sharp left":{"default":"您已经到达您的{nth}个目的地,目的地在道路左侧","upcoming":"您即将到达您的{nth}个目的地,目的地在道路左侧","short":"已到达目的地","short-upcoming":"即将到达目的地","named":"您已到达{waypoint_name},目的地在您左边。"},"sharp right":{"default":"您已经到达您的{nth}个目的地,目的地在道路右侧","upcoming":"您即将到达您的{nth}个目的地,目的地在道路右侧","short":"已到达目的地","short-upcoming":"即将到达目的地","named":"您已到达{waypoint_name},目的地在您右边。"},"slight right":{"default":"您已经到达您的{nth}个目的地,目的地在道路左侧","upcoming":"您即将到达您的{nth}个目的地,目的地在道路左侧","short":"已到达目的地","short-upcoming":"即将到达目的地","named":"您已到达{waypoint_name},目的地在您右边。"},"slight left":{"default":"您已经到达您的{nth}个目的地,目的地在道路右侧","upcoming":"您即将到达您的{nth}个目的地,目的地在道路右侧","short":"已到达目的地","short-upcoming":"即将到达目的地","named":"您已到达{waypoint_name},目的地在您左边。"},"straight":{"default":"您已经到达您的{nth}个目的地,目的地在您正前方","upcoming":"您即将到达您的{nth}个目的地,目的地在您正前方","short":"已到达目的地","short-upcoming":"即将到达目的地","named":"您已到达{waypoint_name},目的地在您前方。"}},"continue":{"default":{"default":"{modifier}行驶","name":"在{way_name}上继续{modifier}行驶","destination":"{modifier}行驶,{destination}方向","exit":"{modifier}行驶,驶入{way_name}"},"straight":{"default":"继续直行","name":"在{way_name}上继续直行","destination":"继续直行,前往{destination}","distance":"继续直行{distance}","namedistance":"继续在{way_name}上直行{distance}"},"sharp left":{"default":"前方左急转弯","name":"前方左急转弯,继续在{way_name}上行驶","destination":"左急转弯,前往{destination}"},"sharp right":{"default":"前方右急转弯","name":"前方右急转弯,继续在{way_name}上行驶","destination":"右急转弯,前往{destination}"},"slight left":{"default":"前方稍向左转","name":"前方稍向左转,继续在{way_name}上行驶","destination":"稍向左转,前往{destination}"},"slight right":{"default":"前方稍向右转","name":"前方稍向右转,继续在{way_name}上行驶","destination":"前方稍向右转,前往{destination}"},"uturn":{"default":"前方调头","name":"前方调头,继续在{way_name}上行驶","destination":"前方调头,前往{destination}"}},"depart":{"default":{"default":"出发向{direction}","name":"出发向{direction},驶入{way_name}","namedistance":"出发向{direction},在{way_name}上继续行驶{distance}"}},"end of road":{"default":{"default":"{modifier}行驶","name":"{modifier}行驶,驶入{way_name}","destination":"{modifier}行驶,前往{destination}"},"straight":{"default":"继续直行","name":"继续直行,驶入{way_name}","destination":"继续直行,前往{destination}"},"uturn":{"default":"在道路尽头调头","name":"在道路尽头调头驶入{way_name}","destination":"在道路尽头调头,前往{destination}"}},"fork":{"default":{"default":"在岔道保持{modifier}","name":"在岔道口保持{modifier},驶入{way_name}","destination":"在岔道口保持{modifier},前往{destination}"},"slight left":{"default":"在岔道口保持左侧行驶","name":"在岔道口保持左侧行驶,驶入{way_name}","destination":"在岔道口保持左侧行驶,前往{destination}"},"slight right":{"default":"在岔道口保持右侧行驶","name":"在岔道口保持右侧行驶,驶入{way_name}","destination":"在岔道口保持右侧行驶,前往{destination}"},"sharp left":{"default":"在岔道口左急转弯","name":"在岔道口左急转弯,驶入{way_name}","destination":"在岔道口左急转弯,前往{destination}"},"sharp right":{"default":"在岔道口右急转弯","name":"在岔道口右急转弯,驶入{way_name}","destination":"在岔道口右急转弯,前往{destination}"},"uturn":{"default":"前方调头","name":"前方调头,驶入{way_name}","destination":"前方调头,前往{destination}"}},"merge":{"default":{"default":"{modifier}并道","name":"{modifier}并道,驶入{way_name}","destination":"{modifier}并道,前往{destination}"},"straight":{"default":"直行并道","name":"直行并道,驶入{way_name}","destination":"直行并道,前往{destination}"},"slight left":{"default":"稍向左并道","name":"稍向左并道,驶入{way_name}","destination":"稍向左并道,前往{destination}"},"slight right":{"default":"稍向右并道","name":"稍向右并道,驶入{way_name}","destination":"稍向右并道,前往{destination}"},"sharp left":{"default":"急向左并道","name":"急向左并道,驶入{way_name}","destination":"急向左并道,前往{destination}"},"sharp right":{"default":"急向右并道","name":"急向右并道,驶入{way_name}","destination":"急向右并道,前往{destination}"},"uturn":{"default":"前方调头","name":"前方调头,驶入{way_name}","destination":"前方调头,前往{destination}"}},"new name":{"default":{"default":"继续{modifier}","name":"继续{modifier},驶入{way_name}","destination":"继续{modifier},前往{destination}"},"straight":{"default":"继续直行","name":"继续在{way_name}上直行","destination":"继续直行,前往{destination}"},"sharp left":{"default":"前方左急转弯","name":"前方左急转弯,驶入{way_name}","destination":"左急转弯,前往{destination}"},"sharp right":{"default":"前方右急转弯","name":"前方右急转弯,驶入{way_name}","destination":"右急转弯,前往{destination}"},"slight left":{"default":"继续稍向左","name":"继续稍向左,驶入{way_name}","destination":"继续稍向左,前往{destination}"},"slight right":{"default":"继续稍向右","name":"继续稍向右,驶入{way_name}","destination":"继续稍向右,前往{destination}"},"uturn":{"default":"前方调头","name":"前方调头,上{way_name}","destination":"前方调头,前往{destination}"}},"notification":{"default":{"default":"继续{modifier}","name":"继续{modifier},驶入{way_name}","destination":"继续{modifier},前往{destination}"},"uturn":{"default":"前方调头","name":"前方调头,驶入{way_name}","destination":"前方调头,前往{destination}"}},"off ramp":{"default":{"default":"下匝道","name":"下匝道,驶入{way_name}","destination":"下匝道,前往{destination}","exit":"从{exit}出口驶出","exit_destination":"从{exit}出口驶出,前往{destination}"},"left":{"default":"下左侧匝道","name":"下左侧匝道,上{way_name}","destination":"下左侧匝道,前往{destination}","exit":"从左侧{exit}出口驶出","exit_destination":"从左侧{exit}出口驶出,前往{destination}"},"right":{"default":"下右侧匝道","name":"下右侧匝道,驶入{way_name}","destination":"下右侧匝道,前往{destination}","exit":"从右侧{exit}出口驶出","exit_destination":"从右侧{exit}出口驶出,前往{destination}"},"sharp left":{"default":"急向左下匝道","name":"急向左下匝道,驶入{way_name}","destination":"急向左下匝道,前往{destination}","exit":"从左侧{exit}出口驶出","exit_destination":"从左侧{exit}出口驶出,前往{destination}"},"sharp right":{"default":"急向右下匝道","name":"急向右下匝道,驶入{way_name}","destination":"急向右下匝道,前往{destination}","exit":"从右侧{exit}出口驶出","exit_destination":"从右侧{exit}出口驶出,前往{destination}"},"slight left":{"default":"稍向左下匝道","name":"稍向左下匝道,驶入{way_name}","destination":"稍向左下匝道,前往{destination}","exit":"从左侧{exit}出口驶出","exit_destination":"从左侧{exit}出口驶出,前往{destination}"},"slight right":{"default":"稍向右下匝道","name":"稍向右下匝道,驶入{way_name}","destination":"稍向右下匝道,前往{destination}","exit":"从右侧{exit}出口驶出","exit_destination":"从右侧{exit}出口驶出,前往{destination}"}},"on ramp":{"default":{"default":"上匝道","name":"上匝道,驶入{way_name}","destination":"上匝道,前往{destination}"},"left":{"default":"上左侧匝道","name":"上左侧匝道,驶入{way_name}","destination":"上左侧匝道,前往{destination}"},"right":{"default":"上右侧匝道","name":"上右侧匝道,驶入{way_name}","destination":"上右侧匝道,前往{destination}"},"sharp left":{"default":"急向左上匝道","name":"急向左上匝道,驶入{way_name}","destination":"急向左上匝道,前往{destination}"},"sharp right":{"default":"急向右上匝道","name":"急向右上匝道,驶入{way_name}","destination":"急向右上匝道,前往{destination}"},"slight left":{"default":"稍向左上匝道","name":"稍向左上匝道,驶入{way_name}","destination":"稍向左上匝道,前往{destination}"},"slight right":{"default":"稍向右上匝道","name":"稍向右上匝道,驶入{way_name}","destination":"稍向右上匝道,前往{destination}"}},"rotary":{"default":{"default":{"default":"进入环岛","name":"通过环岛后驶入{way_name}","destination":"通过环岛后前往{destination}"},"name":{"default":"进入{rotary_name}环岛","name":"通过{rotary_name}环岛后驶入{way_name}","destination":"通过{rotary_name}环岛后前往{destination}"},"exit":{"default":"进入环岛后从{exit_number}出口驶出","name":"进入环岛后从{exit_number}出口驶出,上{way_name}","destination":"进入环岛后从{exit_number}出口驶出,前往{destination}"},"name_exit":{"default":"进入{rotary_name}环岛后从{exit_number}出口驶出","name":"进入{rotary_name}环岛后从{exit_number}出口驶出,上{way_name}","destination":"进入{rotary_name}环岛后从{exit_number}出口驶出,前往{destination}"}}},"roundabout":{"default":{"exit":{"default":"进入环岛后从{exit_number}出口驶出","name":"进入环岛后从{exit_number}出口驶出,上{way_name}","destination":"进入环岛后从{exit_number}出口驶出,前往{destination}"},"default":{"default":"进入环岛","name":"通过环岛后驶入{way_name}","destination":"通过环岛后前往{destination}"}}},"roundabout turn":{"default":{"default":"{modifier}转弯","name":"{modifier}转弯,驶入{way_name}","destination":"{modifier}转弯,前往{destination}"},"left":{"default":"左转","name":"左转,驶入{way_name}","destination":"左转,前往{destination}"},"right":{"default":"右转","name":"右转,驶入{way_name}","destination":"右转,前往{destination}"},"straight":{"default":"继续直行","name":"继续直行,驶入{way_name}","destination":"继续直行,前往{destination}"}},"exit roundabout":{"default":{"default":"驶离环岛","name":"驶离环岛,驶入{way_name}","destination":"驶离环岛,前往{destination}"}},"exit rotary":{"default":{"default":"驶离环岛","name":"驶离环岛,驶入{way_name}","destination":"驶离环岛,前往{destination}"}},"turn":{"default":{"default":"{modifier}转弯","name":"{modifier}转弯,驶入{way_name}","destination":"{modifier}转弯,前往{destination}"},"left":{"default":"左转","name":"左转,驶入{way_name}","destination":"左转,前往{destination}"},"right":{"default":"右转","name":"右转,驶入{way_name}","destination":"右转,前往{destination}"},"straight":{"default":"直行","name":"直行,驶入{way_name}","destination":"直行,前往{destination}"}},"use lane":{"no_lanes":{"default":"继续直行"},"default":{"default":"{lane_instruction}"}}}}

This comment was marked as resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Included OSRMTI as a submodule.

class OfflineRoutingTests: XCTestCase {

override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: remove boilerplate code.

func testOfflineDirections() {
let bundle = Bundle(for: OfflineRoutingTests.self)
let tilesPath = bundle.bundlePath.appending("/routing/liechtenstein")
let translationsPath = bundle.bundlePath.appending("/routing/translations")

This comment was marked as resolved.

@try {
return [self configureRouterForTilesPath:tilesPath translationsPath:translationsPath];
} @catch (NSException *exception) {
return -1;
Copy link
Contributor

@1ec5 1ec5 Oct 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like we’re trying to run around unexpected exceptions coming out of MapboxNavigationNative. If -configureRouterForTilesPath:translationsPath: has expected failure modes, it should be the responsibility of MapboxNavigationNative to catch an exception and turn it into a C-style return code and NSError out parameter.

By default, throwing an exception in Objective-C causes a leak, even under ARC, because the expectation is that an exception is a catastrophic error that leads to an immediate crash anyways. That’s one reason Objective-C programmers generally avoid @try-@catch, even in cases where C++ programmers might rely on it for control flow. It doesn’t leak in Objective-C++, but whether the @throw happens in Objective-C or Objective-C++ is none of this SDK’s business.

Copy link
Contributor Author

@frederoni frederoni Oct 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning NSErrors from Obj-C has a really poor bridgeability to Swift’s "throws". Noticed that this try-catch block doesn't suppress the underlying exception so I ended up removing it altogether. It's just a fallback for the kind of resource the offline router is looking for. (1: Uncompress tiles, 2: Compressed tiles, 3: Different structure of compressed tiles). It's not a fatal error but one that gets caught if you have "Catch all Exceptions" enabled.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning NSErrors from Obj-C has a really poor bridgeability to Swift’s "throws".

Unless I’m mistaken, the most idiomatic method signature would include an NSError ** out parameter, which would bridge to Swift as a throws, but it wouldn’t return an error.

Copy link
Contributor Author

@frederoni frederoni Oct 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the most idiomatic method signature would include an NSError ** out parameter

this is correct but there are some limitations, a boolean is the only supported primitive return type:

- (void)voidNoThrow:(int)arg error:(NSError **)error;      // Bridges to NSErrorPointer
- (NSUInteger)intNoThrow:(int)arg error:(NSError **)error; // Bridges to NSErrorPointer
- (BOOL)boolThrow:(int)arg error:(NSError **)error;        // Throws idiomatically

However, there seems to be a consensus about using -fno-exceptions eventually, partially due to bloated binary size but the inevitable leak in Obj-C is also a good point. Either way, this try-catch block is already removed.


@interface MBNavigator (additions)

- (NSUInteger)setupRouter:(NSString *)tilesPath translationsPath:(NSString *)translationsPath;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation would be great here. It wasn’t obvious to me that the return value is a tile count. From the implementation of this method, I initially got the impression that it was an error code of some sort.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is not relevant any longer. configureRouter is not wrapped in setUpRouter but instead called directly from an initializer in Swift which is documented.

}

@objc(MBMapboxOfflineDirections)
public class MapboxOfflineDirections: Directions, OfflineRoutingProtocol {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the name of this class. How about NavigationDirections?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s as good a name as I can think of. Hopefully developers don’t end up thinking they can only use NavigationRouteOptions with this class.

@objc(MBMapboxOfflineDirections)
public class MapboxOfflineDirections: Directions, OfflineRoutingProtocol {

public required init(tilesPath: URL, translationsPath: URL, accessToken: String?, host: String? = nil, completionHandler: @escaping OfflineDirectionsCompletionHandler) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename tilesPath and translationsPath to tilesURL and instructionsURL, respectively, since they’re no longer path strings.

Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are any changes to documentation needed?

  • README
  • CHANGELOG
  • jazzy table of contents
  • jazzy cover page

@frederoni
Copy link
Contributor Author

frederoni commented Oct 26, 2018

Are any changes to documentation needed?

Yep, we do need some additions to the documentation, but I figured, since we're targeting a feature branch (offline-routing) and api-routing-tiles is not yet deployed to production, this is subject to change. Updates to the README and a guide on how to use the offline tile downloader is slated for a subsequent PR.

@frederoni frederoni merged commit de5e5bf into offline-routing Oct 29, 2018
@frederoni frederoni mentioned this pull request Nov 1, 2018
7 tasks
@annathomasQB
Copy link

Hi @frederoni ,

I'm trying to implement offline routing with the examples provided in the documents. But it doesn't seem to work. I'm trying to figure out where I might have gone wrong. I'm getting the tiles downloaded (is the max limit set to 10?) for Faroe Islands, unpacked at URL - all that's happening... I'm guessing the configureRouter too is getting set properly. Is there anything else left to be done ? how do I assign this to the navigationController? I've raised my issue here : Downloaded Tiles not shown for Offline Routing

@1ec5 1ec5 deleted the fred/offline-routing branch December 5, 2019 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants