Writing a tweak

This page covers what applies to any DuoDash integration, whichever Core Tweak it uses: how a tweak registers, what a provider’s life looks like from load to disconnect, and how to fail safely when the things you depend on are missing.

The Developer API is not published yet. Every symbol and manifest 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

Registration

Third-party integrations register themselves with Tweak Management. Registration is what lets DuoDash identify the tweak name, developer, version, supported application, supported Core Tweaks, capabilities and compatibility requirements.

A conceptual manifest:

{
  "identifier": "com.example.googlemaps.duodash",
  "name": "Google Maps DuoDash Integration",
  "version": "1.0.0",
  "developer": "Example Developer",
  "targetApplications": [
    "com.google.Maps"
  ],
  "capabilities": [
    "navigation-bubble",
    "voice-command"
  ]
}

This manifest format is an architectural example only. The final registration format will match the official DuoDash implementation.

Capability model

Request only the DuoDash capabilities you actually use. The current capabilities are:

navigation-bubble
voice-command

Future DuoDash versions may expose additional capabilities. Capability-based registration is what makes it possible for DuoDash to determine what an installed tweak is allowed or expected to interact with.

A single third-party tweak may support multiple cores. Each DuoDash Core stays independent:

Google Maps Integration
│
├── Speed Provider
│       │
│       └──► Navigation Bubble
│
└── Voice Command Handler
        │
        └──► Google Maps Voice Search

That tweak’s manifest would declare both navigation-bubble and voice-command.

Checking DuoDash is available

Always verify that the required DuoDash component is available before attempting to use it:

if (DuoDashNavigationBubbleAvailable()) {
    // Register provider.
}

Your tweak must continue to function safely when DuoDash is not installed, when the installed DuoDash version is incompatible, when the required Core Tweak is disabled, when CarPlay is disconnected, and when Tweak Management is disabled altogether.

The absence of DuoDash must not cause the target application to crash.

Provider lifecycle

A typical provider lifecycle runs:

Tweak Loaded
    │
    ▼
Check DuoDash Availability
    │
    ▼
Check Required Core Capability
    │
    ▼
Register Provider
    │
    ▼
Target Application Becomes Active
    │
    ▼
Begin Data / Event Integration
    │
    ▼
Application State Changes
    │
    ▼
Update DuoDash
    │
    ▼
Application Terminates or Provider Stops
    │
    ▼
Invalidate Current Data
    │
    ▼
Unregister / Disconnect

The last two steps are the ones most often skipped, and they are what keep a dead provider’s last value off the driver’s dashboard.

CarPlay connection state

Not every data update needs to be processed while CarPlay is disconnected. Where the DuoDash API supports it, providers may observe connection state:

CarPlay disconnected
       │
       ▼
Pause unnecessary provider updates

CarPlay connected
       │
       ▼
Resume provider

DuoDash session becomes active
       │
       ▼
Publish current state

The official API will define whether connection management is handled automatically by DuoDash or exposed to providers.

Recommended provider architecture

Separate application-specific extraction from DuoDash integration:

GoogleMapsSpeedExtractor
        │
        │ raw application data
        ▼
GoogleMapsSpeedProvider
        │
        │ normalized data
        ▼
DuoDashNavigationProvider

Rather than one large hook containing app hooks, speed conversion, DuoDash IPC, UI state and lifecycle management all together.

Separating these responsibilities is what makes an integration maintainable when either DuoDash or the target application changes — and one of them always does.

Suggested project structure

A third-party integration may use a structure similar to:

MyDuoDashIntegration/
│
├── Hooks/
│   ├── AppHooks.xm
│   └── NavigationHooks.xm
│
├── Providers/
│   ├── SpeedProvider.h
│   └── SpeedProvider.m
│
├── DuoDash/
│   ├── DuoDashBridge.h
│   └── DuoDashBridge.m
│
├── Voice/
│   ├── VoiceCommandHandler.h
│   └── VoiceCommandHandler.m
│
├── Support/
│   └── Compatibility.m
│
├── Tweak.xm
└── Makefile

The exact structure is optional. The principle that matters is keeping the application’s reverse-engineered or application-specific behaviour separated from the DuoDash API layer.

Application-specific hooks

DuoDash does not define how you extract information from another application. Use whichever mechanism suits your supported environment:

Objective-C method hooks
Runtime inspection
Application notifications
Internal model observation
C/C++ hooks
Application-specific callbacks

Application internals change between application versions. You are responsible for validating compatibility with the versions of your target application that you claim to support, and for saying which those are.

Threading

Application hooks may execute on different threads. Do not assume that:

  • Application callbacks occur on the main thread.
  • DuoDash callbacks occur on the main thread.
  • Vehicle events occur on the application UI thread.

Perform the required synchronization before updating application UI or shared state:

dispatch_async(dispatch_get_main_queue(), ^{
    [ApplicationIntegration activateVoiceInterface];
});

Follow the target application’s own threading requirements.

Error handling

A third-party integration must fail safely. If the provider cannot obtain valid data:

Do not send fabricated data.
Do not continuously retry at high frequency.
Do not crash the host application.
Do not block the main thread.

Instead:

Mark provider data unavailable
        │
        ▼
Optionally log diagnostic information
        │
        ▼
Wait for the source to recover
        │
        ▼
Resume normal updates

Logging

During development, provide meaningful logs for integration failures. Useful information includes:

Provider identifier
Provider version
Target application version
DuoDash API version
Core Tweak availability
Registration status
Last successful data update
Last received event
Provider state

Do not continuously log high-frequency values such as every raw speed sample unless explicit debug logging is enabled.

Security and trust model

Third-party tweaks execute in a jailbroken environment and may interact with applications using hooks or runtime modification. DuoDash cannot guarantee the behaviour, security or stability of independently developed third-party tweaks.

Developers should:

  • Validate all data before sending it to DuoDash.
  • Validate all data received from DuoDash.
  • Avoid unsafe pointer assumptions.
  • Avoid blocking vehicle-related event callbacks.
  • Avoid unnecessary access to user information.
  • Avoid collecting data unrelated to the tweak’s documented functionality.
  • Avoid interfering with other DuoDash providers.

Driver safety

Design your integration with driving safety as a primary constraint. A vehicle interface is fundamentally different from a normal phone interface.

Do not introduce interactions that require excessive visual attention or complex touch input while driving. In particular, avoid:

  • Large amounts of constantly changing information.
  • Complex menus intended for interaction while driving.
  • Unnecessary notifications.
  • Rapidly flashing elements.
  • Controls requiring precise touch interaction.
  • Actions that unexpectedly obscure navigation information.

Vehicle controls exposed by DuoDash should only be used for predictable and clearly understood actions.

Before you release

Verify all of the following:

  • The tweak loads without DuoDash installed.
  • The tweak handles an unsupported DuoDash version safely.
  • Navigation Bubble provider registration succeeds.
  • Speed values are correctly normalized.
  • Speed units are correct.
  • Invalid speed data is rejected.
  • Stale data is removed.
  • Closing the target application clears provider state.
  • CarPlay disconnect does not cause a crash.
  • CarPlay reconnect restores the integration correctly.
  • Voice command events are handled correctly.
  • One vehicle event does not unintentionally trigger multiple actions.
  • Application UI operations occur on the correct thread.
  • Unsupported application versions fail safely.
  • Logging does not generate excessive output.
  • The integration does not noticeably impact application performance.
  • The integration has been tested in an actual vehicle, or a representative CarPlay environment, before release.

The last one is not optional. A bench test with a CarPlay simulator will not reproduce how a given head unit reports its voice button, and that is exactly where integrations break.

API reference

To be published when the DuoDash Developer API is finalised. It will cover the Tweak Management header, the API version query, capability queries, provider metadata and connection state.

Not yet available. Get in touch to be told when it is published.

Next: the open-source OBD-II dongle platform →