Navigation Bubble presents lightweight navigation information — speed above all — on the DuoDash interface. This page covers how a third-party tweak feeds it data from an application it supports.
The Developer API is not published yet. Every symbol on this page is an illustrative placeholder, not the final DuoDash SDK. The architecture and the rules are what to design against; the names are not. Developer guide overview
On this page
Purpose
Navigation Bubble is a DuoDash Core Tweak that presents lightweight navigation-related information on the DuoDash interface. One of its primary uses is displaying speed information.
A third-party tweak obtains speed or other supported navigation information from an application and provides it to Navigation Bubble. Navigation Bubble is responsible for presenting the information; your tweak is responsible for obtaining and interpreting the original data.
Do not attempt to manipulate Navigation Bubble UI elements directly. Provide normalized data to DuoDash and let it render.
Data flow
A typical integration works as follows.
Target Navigation App
│
│ 1. Third-party tweak observes app
▼
Application-Specific Tweak
│
│ 2. Extract speed/navigation data
│ 3. Normalize data
▼
DuoDash Navigation Bubble API
│
│ 4. Validate/update
▼
Navigation Bubble
│
│ 5. Render
▼
CarPlay / DuoDash UI
Example: a speed provider
Suppose you are writing a tweak for a navigation application that internally exposes the current vehicle speed. The tweak would:
- Observe the relevant application object or data source.
- Extract the current speed.
- Determine the unit used by the source application.
- Convert or normalize the value if required.
- Send the value to Navigation Bubble.
- Continue providing updates while the source remains valid.
Conceptually:
// Illustrative example only.
// Replace with the official DuoDash API when available.
DDNavigationBubbleData *data = [DDNavigationBubbleData new];
data.speed = currentSpeed;
data.speedUnit = DDSpeedUnitKPH;
data.sourceIdentifier = @"com.example.navigation";
[[DDNavigationBubble sharedInstance] updateData:data];
The classes and methods above are illustrative placeholders. They do not represent the final DuoDash SDK or API.
Recommended data model
The final DuoDash API may expose some or all of the following fields:
speed
speedUnit
speedLimit
speedLimitUnit
sourceIdentifier
timestamp
accuracy
valid
Possible future navigation fields may include:
distanceToNextTurn
nextTurnType
nextStreetName
remainingDistance
estimatedArrivalTime
routeState
Only provide fields for which you have reliable data. Do not fabricate missing values.
Source identification
Every third-party provider should have a unique source identifier. The recommended format is:
<developer>.<application>.<provider>
For example:
com.example.googlemaps.speedprovider
or, if bundle identifiers are used:
com.google.Maps
The final identifier format will follow the DuoDash SDK specification. Source identifiers are what allow DuoDash to:
- Track the active provider.
- Detect stale providers.
- Handle application switching.
- Resolve multiple providers.
- Display diagnostic information.
- Prevent unrelated tweaks from accidentally overwriting each other’s state.
Data lifetime
A third-party tweak should explicitly distinguish between:
- Valid current data.
- Temporarily unavailable data.
- Stale data.
- Provider disconnected.
- Application terminated.
A provider must not leave an old speed value active indefinitely after its application has stopped producing information. A stale number on a dashboard is worse than no number, because the driver has no way to tell it is stale.
App running:
72 km/h
App stops producing speed:
INVALID / unavailable
App terminated:
Provider disconnected
DuoDash may additionally implement a timeout mechanism to invalidate stale provider data.
Update frequency
Providers should avoid sending unnecessarily high-frequency updates. For UI information such as speed, update only when:
- The value changes.
- The data becomes invalid.
- The unit changes.
- The source state changes.
- A meaningful update interval has elapsed.
Do not send updates every display frame. Excessive updates waste CPU time and may negatively affect both the iPhone and the CarPlay environment.
Full integration example
A complete conceptual integration, showing availability checks, registration, the invalid-data path and teardown:
// PSEUDOCODE — NOT FINAL DUODASH API
@interface ExampleSpeedProvider : NSObject
@end
@implementation ExampleSpeedProvider
- (void)start
{
if (!DDIsAvailable()) {
return;
}
if (!DDCapabilityAvailable(@"navigation-bubble")) {
return;
}
DDRegisterProvider(@"com.example.speedprovider");
[self startObservingApplicationSpeed];
}
- (void)applicationSpeedChanged:(double)speed
{
if (speed < 0) {
DDNavigationSetUnavailable(
@"com.example.speedprovider"
);
return;
}
DDNavigationUpdateSpeed(
@"com.example.speedprovider",
speed,
DDSpeedUnitKPH
);
}
- (void)stop
{
DDNavigationSetUnavailable(
@"com.example.speedprovider"
);
DDUnregisterProvider(
@"com.example.speedprovider"
);
}
@end
All DD* symbols shown above are placeholders.
API reference
To be published when the DuoDash Developer API is finalised. It will cover the Navigation Bubble header, provider registration, the speed update call, invalidating data and unregistering.
Not yet available. Get in touch to be told when it is published.
Next: registering a tweak, provider lifecycle and the release checklist →