/ ionic

Ionic 2 text to speech native plugin tutorial

The ionic framework version 2 has is well into becoming a stable framework, so I thought it was time to write about some of the features that you can start using today. The ionic framework is still waiting for its final release but the release candidates so far have really been exciting and making mobile and PWA apps a breeze to build.

This post is a first in a series of posts that will cover a lot of the components and mobile native features that are available today. I will be covering the text-to-speech native wrapper. If you aren't sure what a native wrapper is in an ionic context then here is a brief explanation from the ionic documentation.

Ionic Native is a curated set of ES5/ES6/TypeScript wrappers for Cordova/PhoneGap plugins that make adding any native functionality you need to your Ionic, Cordova, or Web View mobile app easy.

There are many uses for the text-to-speech native plugin such as apps that involve learning a foreign language or accessibility features where text can be spoken out loud through the users mobile phone. In this example I am going to create a simple list of words with a play button next to each item which will use your phones native text to speech functionality.

Prerequisites

There are a few things that I won't be covering here in this tutorial in much detail so it would be a good idea to learn some of the basics before diving in. Make sure that you have node and npm installed to their latest stable versions.

Step 1

The first step is to make sure that you have the latest version of the ionic framework and cordova installed. Fire up your console window (I use iTerm 2) and type in the following command.

npm install -g ionic cordova

Step 2

Navigate to a folder on your computer where you are going to create this new project.

cd ~/code/apps/

This is where I have decided to build my app, yours may differ. Next run the following command

ionic start textToSpeech blank --v2

This will add a folder in the current directory with your project name, mine is textToSpeech using version 2 of the ionic framework. If you miss off the --v2 flag it will create the project using ionic v1, we don't want that to happen!

Step 3

Change your directory to the newly added ionic project.

cd textToSpeech

And to test that everything has worked run the following command:

ionic serve

This will build your project and automatically open it in a browser tab. You should now see something like this:

Step 4

Now we can add our native text-to-speech plugin. Stop the app from running in the console by hitting ctrl + c. We can now import the native plugin by typing:

ionic plugin add cordova-plugin-tts

After this has completed we then need to import the plugin into our app. Open your project folder into your favourite Text editor or IDE. I use sublimetext 3. Expand the src folder, this is where we will be editing our pages.

In the src folder you should see pages > home > home.ts. Open this file. You should see the code below:

import { Component } from '@angular/core';

import { NavController } from 'ionic-angular';

@Component({
	selector: 'page-home',
	templateUrl: 'home.html'
})
export class HomePage {

	constructor() {

	}

}

To import the plugin we need to add the code below at the top with the other imports. You can remove the NavController import and public member from the constructor, we won't be using this:

import {TextToSpeech} from 'ionic-native';

Step 5

Staying in the home.ts file we are going to add an array or words that we will list out in the home template. Start by adding a member variable to the class and then populating it with data in the constructor.

import { Component } from '@angular/core';
import { TextToSpeech } from 'ionic-native';

@Component({
	selector: 'page-home',
	templateUrl: 'home.html'
})
export class HomePage {

	public words: any

	constructor() {

		this.words = [
			{ text: 'Mercury' },
			{ text: 'Venus' },
			{ text: 'Earth' },
			{ text: 'Mars' },
			{ text: 'Jupiter' }, 
			{ text: 'Saturn' },
			{ text: 'Uranus' }, 
			{ text: 'Neptune' }
		]

	}

}

Step 6

Now open the home.html template file, remove the html in between the <ion-content> tags and add the list component code below:

<ion-header>
	<ion-navbar>
		<ion-title>
			Ionic Planets
		</ion-title>
	</ion-navbar>
</ion-header>

<ion-content padding>

	<ion-list>

		<ion-item *ngFor="let word of words">
			{{ word.text }}
			<button ion-button outline color="secondary" item-right icon-right (click)="speak(word.text)">
				Play
				<ion-icon icon-only name="play"></ion-icon>
			</button>
		</ion-item>

	</ion-list>

</ion-content>

So what have we done here? I have added the <ion-list> component and iterated through the array of words adding each word as a <ion-item>. I have added a play button as we are going to click the item to trigger the click event that I have also added. The click event will trigger a method called speak() that we haven't yet created. We will pass in the word as an argument. I have also changed the page title to Ionic Planets

Step 7

Now we can add the speak method to the class. Open the home.ts file and under the constructor function add a method:

speak(word:string):void {
    console.log("Word:", word);
}

This method accepts an argument of type string. The :void part is added as we are not returning any values from the method. For now we are just logging the word to the console. Go back to your terminal and start your development server up again by typing:

ionic serve -b

If you kept your app open in the browser the -b flag will start the serve without opening a new tab. You can just refresh the previously opened tab to see your changes. If you did close it just remove the -b flag. Your app should now look like this:

When you click on the play button in a list item it should log the word to the console. The next step is to get the word spoken by your device.

Step 8

Now we can add the native wrapper code to the speak method.

speak(word:string):void {

    const options = {
    	text: word,
        rate: 1.55
    }

    TextToSpeech.speak(options)
    .then(() => console.log('Success'))
    .catch((reason: any) => console.log(reason));

}

Here we have added an options const that passes values into the TextToSpeech.speak() function. These options contain the word that we passed in as an argument and the speech rate. There is a promise .then() that triggers on success and a .catch() that triggers on error. Both output to the console.

If you now go to your app in the browser and click on a list item play button, you should see the error cordova_not_available sent to the console. This is because cordova and the native plugins aren't available in a web browser. We need to test in a simulator or a real device.

Step 9

When ionic first set up your app with the start command it automatically installed the ios platform. You could also install the android platform but for now we will be testing on ios. Testing on android is similar and will go through the set up in a separate post.

So ctrl + c in the terminal to quit and stop your app. If you now type:

ionic emulate ios

This will build your app for ios and load up the ios simulator. It takes a minute or 2 so be patient. If the simulator doesn't display, check your dock as it doesn't always appear above your other open windows.

After the app has loaded in the simulator click on any list item play button, you should hear the word spoken out loud.

Pretty easy eh?

One last thing to tidy things up is to disable the other list items when an item is clicked. This is so you can't go click happy and slow your device down by firing off loads of click events.

Step 10

Add another member variable to the home class.

public disableBtns:boolean = false

And then add an attribute to the play button passing in the boolean value. We initially set the variable to false so the buttons are enabled.

[disabled]="disableBtns"

<button ion-button outline color="secondary" item-right icon-right [disabled]="disableBtns" (click)="speak(word.text)">
				Play
				<ion-icon icon-only name="play"></ion-icon>
			</button>

We then edit our speak method to first set the buttons to disabled = true when the play button is clicked and then disabled = false when the .then() promise is triggered and also if there was an error.

speak(word:string):void {

    this.disableBtns = true

    const options = {
    	text: word,
        locale: 'en-GB',
        rate: 1.55
    }

    TextToSpeech.speak(options)
        .then(() => {
            console.log('Success')
            this.disableBtns = false
        })
        .catch((reason: any) => {
            console.log(reason)
            this.disableBtns = false
        })
}

You then need to run ionic emulate ios to view these changes.

And that's it! You now have an app that can convert text to speech. The voice that is used will the voice that is set up by the simulator or if you are testing on a device it will be the default voice or the one you have chosen in your phone's settings.