AnkiMobile: API to invoke native iOS TTS with runtime text from card JavaScript

Hi,

I’m using AnkiMobile on iOS and would like to use the system’s high-quality/premium voices for TTS from card JavaScript.

Current situation

On iOS, I have downloaded and selected:

Settings → Accessibility → Spoken Content → Voices → English → Zoe (Premium)

AnkiMobile’s built-in TTS can use this voice successfully with the {{tts}} syntax, for example:

{{tts en_US voices=Apple_Zoe_(Premium):Word}}

However, I have a different use case.

I want to define a JavaScript function such as:

function speak(text) {
    // speak the text using the iOS system TTS voice
}

speak("apple");
speak("The cat is sitting on the table.");

The text is generated dynamically at runtime, so it is not known when the card template is rendered.

Why speechSynthesis doesn’t solve this

Currently I can use:

const utterance = new SpeechSynthesisUtterance(text);
speechSynthesis.speak(utterance);

This works with dynamically generated text, but on iOS the Web Speech API does not expose all voices installed in the system.

In particular, speechSynthesis.getVoices() does not return Zoe (Premium) even though Zoe is installed and selected as the English voice in iOS Settings.

Therefore I cannot select Zoe using:

utterance.voice = ...

The problem seems to be related to WebKit’s Web Speech API rather than Anki itself.

What I would like AnkiMobile to provide

Would it be possible for AnkiMobile to expose a JavaScript API that allows card templates to invoke AnkiMobile’s native TTS implementation with arbitrary runtime text?

For example, something conceptually like:

AnkiMobile.tts.speak({
    text: "Hello world",
    language: "en_US",
    voice: "Apple_Zoe_(Premium)"
});

Or even a simpler API such as:

AnkiMobile.ttsSpeak(
    "Hello world",
    "en_US",
    "Apple_Zoe_(Premium)"
);

The important part is that text should be supplied at runtime by JavaScript, rather than being fixed in a {{tts}} template tag.

Ideally the API would also allow:

  • specifying the language;

  • specifying the iOS TTS voice;

  • controlling speech rate;

  • stopping/cancelling the current speech;

  • optionally querying the available voices.

For example:

speak(text, {
    language: "en_US",
    voice: "Apple_Zoe_(Premium)",
    rate: 1.0
});

Why this would be useful

This would allow card templates to generate or process text dynamically and still use the high-quality voices provided by the operating system.

For example, a card could obtain a sentence from a field, process it with JavaScript, generate an example sentence, or otherwise construct arbitrary text and then ask AnkiMobile’s native TTS to read it.

The existing {{tts}} functionality is excellent for text known at template-rendering time, but it cannot be used as a general runtime TTS API from JavaScript.

Would this be technically feasible, or is there already an undocumented/recommended way for card JavaScript to invoke AnkiMobile’s native TTS with arbitrary runtime text?

Thanks!

Does anyone care about this matter?

Currently there’s no way to do that as far as I know. Hopefully can be implemented in the future as part of a cross-platform API for templates: Consider a cross-platform add-on system for templates · Issue #3833 · ankitects/anki · GitHub