It’s sometimes nice to add a little sound to your applications, and even better to add a voice. Outside Siri, you can use a cool and simple AVFoundation
API to make iOS devices talk. Let’s learn how to use the Speech synthesizer.
Download the starter file. I’ve made an app for you that has a text field, a button and a segue to a table view we’ll discuss a little later.
Open the ViewController,swift
file. Find the speak
action. We’ll need to get a string from the text field. So add the following code to get the text if the field has a value:
if let speechText = speakingText.text{ }
You’ll need two objects: a synthesizer object and a speech utterance. But before you do, make sure you have imported AVFoundation
.
import AVFoundation
I’ll add the synthesizer with the AVSpeechSynthesizer
class
let synth = AVSpeechSynthesizer() let speech = AVSpeechUtterance(string: speechText) synth.speak(speech)
That’s it. Set your simulator to iPhone 8 Plus. Build and run the app. Type in some phrase, like
I could use a good pizza right now.
Tap the Speak! Button.
Your simulator speaks!!
Of course that’s not the only method you have at your disposal. You can easily change the voice as well. Voices are a localization in pronunciation. Some languages will have more than one available pronunciation. I set up the app to list all the voices and their language combinations on a table view and then the user can select the voice and accent.
You’ll use the AVSpeechSynthesisVoice
class for this. There is a class method that returns an array of voices. I’ll use this for my model for the table
let voices = [AVSpeechSynthesisVoice.speechVoices()] //list of voices
Head down the code to the tableview.dequeue
method. Remove what I have their now. All the voices have, names, Identifiers and languages. Names are only indication if they are male or female voices until you hear them. You use the name property. Since these properties are strings. we can assign the name directly to the text label and the language to the detail text label of the table cell.
cell.textLabel?.text = voice.name cell.detailTextLabel?.text = voice.language
When a language is selected I’ll send that voice back from the table and dismiss the table. I set up the delegation for you. In didselect
, uncomment out the two lines. If you don’t understand what I’m doing here take a look at the delegates and data sources course in the library.
Back in ViewController
, you’ll see I have the delegate method defined to transfer the voice to a variable. All you need to do is assign the voice with the action to the variable.
Speech.voice = speechVoice
Now run. Tap voice and then pick another voice. Try the voice.
Play around with this. Of course, voices are more for localization than entertainment. There’s more to the API, but with these basics you can make your app talk.
The Whole Code
ViewController.swift
// // ViewController.swift // SpeechSynthesizer // // A exercise file for iOS Development Tips Weekly // by Steven Lipton (C)2018, All rights reserved // For videos go to http://bit.ly/TipsLinkedInLearning // For code go to http://bit.ly/AppPieGithub // import UIKit import AVFoundation class ViewController: UIViewController, VoiceTableViewControllerDelegate { @IBOutlet weak var speakingText: UITextField! var speechVoice = AVSpeechSynthesisVoice() @IBAction func speak(_ sender: UIButton) { //<-- Add code here if let speechText = speakingText.text{ let synth = AVSpeechSynthesizer() let speech = AVSpeechUtterance(string: speechText) speech.voice = speechVoice synth.speak(speech) } } //delegate function func didSelectVoice(voice: AVSpeechSynthesisVoice) { speechVoice = voice title = voice.name } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. title = "Default Voice" } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "voices"{ let vc = segue.destination as! VoiceTableViewController vc.delegate = self } } }
VoiceTableViewController.swift
// // VoiceTableViewController.swift // SpeechSynthesizer // // A exercise file for iOS Development Tips Weekly // by Steven Lipton (C)2018, All rights reserved // For videos go to http://bit.ly/TipsLinkedInLearning // For code go to http://bit.ly/AppPieGithub // // A table view controller for selecting a language // import UIKit import AVFoundation protocol VoiceTableViewControllerDelegate{ func didSelectVoice(voice:AVSpeechSynthesisVoice) } class VoiceTableViewController:UITableViewController { let voices = AVSpeechSynthesisVoice.speechVoices() //list of voices var delegate:VoiceTableViewControllerDelegate! = nil override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return voices.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) let row = indexPath.row let voice = voices[row] cell.textLabel?.text = voice.name cell.detailTextLabel?.text = voice.language return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let row = indexPath.row delegate.didSelectVoice(voice: voices[row]) navigationController?.popViewController(animated: true) } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } }
Leave a Reply