The GetWayPoints and SubscribeWayPoints RPCs are designed to allow you to get the navigation destination(s) from the active navigation app if the user is navigating.
The GetWayPoints and SubscribeWayPoints RPCs are restricted by most vehicle manufacturers. As a result, the head unit you are connecting to will reject the request if you do not have the correct permissions. Please check the Understanding Permissions section for more information on how to check permissions for an RPC.
Since there is a possibility that some head units will not support getting the navigation destination, you should check head unit support before attempting to send the request. You should also update your app's UI based on whether or not you can use GetWayPoints.
You can use the SDLSystemCapabilityManager to check the navigation capability returned by Core as shown in the code sample below.
[self.sdlManager.systemCapabilityManager updateCapabilityType:SDLSystemCapabilityTypeNavigation completionHandler:^(NSError * _Nullable error, SDLSystemCapabilityManager * _Nonnull systemCapabilityManager) { BOOL isNavigationSupported = NO; if (error == nil) { isNavigationSupported = systemCapabilityManager.navigationCapability.getWayPointsEnabled.boolValue; } else { isNavigationSupported = systemCapabilityManager.hmiCapabilities.navigation.boolValue; } <#If navigation is supported, send the `GetWayPoints` RPC#> }];
sdlManager.systemCapabilityManager.updateCapabilityType(.navigation) { (error, systemCapabilityManager) in var isNavigationSupported = false if error == nil { isNavigationSupported = systemCapabilityManager.navigationCapability?.getWayPointsEnabled?.boolValue ?? false; } else { isNavigationSupported = systemCapabilityManager.hmiCapabilities?.navigation?.boolValue ?? false } <#If navigation is supported, send the `GetWayPoints` RPC#> }
To subscribe to the waypoints, you will have to set up your callback for whenever the waypoints are updated, then send the SubscribeWayPoints RPC.
// Any time before SDL would send the notification (such as when you call `sdlManager.start` or at initialization of your manager) [self.sdlManager subscribeToRPC:SDLDidReceiveWaypointNotification withObserver:self selector:@selector(waypointsDidUpdate:)]; // Create this method to receive the subscription callback - (void)waypointsDidUpdate:(SDLRPCNotificationNotification *)notification { SDLOnWayPointChange *waypointUpdate = (SDLOnWayPointChange *)notification.notification; NSArray<SDLLocationData> *waypoints = waypointUpdate.wayPoints; <#Use the waypoint data#> } // After SDL has started your connection, at whatever point you want to subscribe, send the subscribe RPC SDLSubscribeWayPoints *subscribeWaypoints = [[SDLSubscribeWayPoints alloc] init]; [self.sdlManager sendRequest:subscribeWaypoints withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { if (error != nil || !response.success) { // Handle the error return; } // You are now subscribed! }];
// Any time before SDL would send the notification (such as when you call `sdlManager.start` or at initialization of your manager) sdlManager.subscribe(to: .SDLDidReceiveWaypoint, observer: self, selector: #selector(waypointsDidUpdate(_:))) // Create this method to receive the subscription callback func waypointsDidUpdate(_ notification: SDLRPCNotificationNotification) { guard let waypointUpdate = notification.notification as? SDLOnWayPointChange, let waypoints = waypointUpdate.wayPoints else { return } <#Use the waypoint data#> } // After SDL has started your connection, at whatever point you want to subscribe, send the subscribe RPC let subscribeWaypoints = SDLSubscribeWayPoints() sdlManager.send(request: subscribeWaypoints) { (request, response, error) in guard error == nil, let response = response, response.success == true else { // Handle the errors return } // You are now subscribed! }
To unsubscribe from waypoint data, you must send the SDLUnsubscribeWayPoints RPC.
You do not have to unsubscribe from the sdlManager.subscribe method, you must simply send the unsubscribe RPC and no more callbacks will be received.
// Whenever you want to unsubscribe SDLUnsubscribeWayPoints *unsubscribeWaypoints = [[SDLUnsubscribeWayPoints alloc] init]; [self.sdlManager sendRequest:unsubscribeWaypoints withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { if (error != nil || !response.success) { // Handle the error return; } // You are now unsubscribed! }];
// Whenever you want to unsubscribe let unsubscribeWaypoints = SDLUnsubscribeWayPoints() sdlManager.send(request: unsubscribeWaypoints) { (request, response, error) in guard error == nil, let response = response, response.success == true else { // Handle the errors return } // You are now subscribed! }
If you only need waypoint data once without an ongoing subscription, you can use GetWayPoints instead of SubscribeWayPoints.
// Whenever you want to get waypoint data SDLGetWayPoints *getWaypoints = [[SDLGetWayPoints alloc] initWithType:SDLWayPointTypeAll]; [self.sdlManager sendRequest:getWaypoints withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { if (error != nil || !response.success) { // Handle the error return; } SDLGetWayPointsResponse *waypointResponse = response; NSArray<SDLLocationDetails *> *waypointLocations = waypointResponse.waypoints; <#Use the waypoint information#> }];
// Whenever you want to unsubscribe let getWaypoints = SDLGetWayPoints(type: .all) sdlManager.send(request: getWaypoints) { (request, response, error) in guard error == nil, let response = response as? SDLGetWayPointsResponse, response.success == true else { // Handle the errors return } let waypointLocations = response.waypoints; <#Use the waypoint information#> }