This chapter was the most challenging so far. This is the code from MainWindowController.swift I ended up with at the end of the chapter 7:
import Cocoa
class MainWindowController: NSWindowController, NSSpeechSynthesizerDelegate,
NSWindowDelegate, NSTableViewDataSource, NSTableViewDelegate {
@IBOutlet weak var textField: NSTextField!
@IBOutlet weak var speakButton: NSButton!
@IBOutlet weak var stopButton: NSButton!
@IBOutlet weak var tableView: NSTableView!
let speechSynth = NSSpeechSynthesizer()
let voices = NSSpeechSynthesizer.availableVoices
var isStarted: Bool = false {
didSet {
updateButtons()
}
}
override var windowNibName: String {
return "MainWindowController"
}
override func windowDidLoad() {
super.windowDidLoad()
updateButtons()
speechSynth.delegate = self
for voice in voices {
print(voiceNameForIdentifier(identifier: voice)!)
}
let defaultVoice = NSSpeechSynthesizer.defaultVoice
if let defaultRow = voices.firstIndex(of: defaultVoice){
let indices = NSIndexSet(index: defaultRow)
tableView.selectRowIndexes(indices as IndexSet, byExtendingSelection: false)
tableView.scrollRowToVisible(defaultRow)
}
}
// MARK: - Action methods
@IBAction func speakIt(sender: NSButton) {
let string = textField.stringValue
if string.isEmpty {
print("string is empty")
} else {
speechSynth.startSpeaking(string)
isStarted = true
}
}
@IBAction func stopIt(sender: NSButton){
//print("stop button clicked")
speechSynth.stopSpeaking()
//isStarted = false
}
func updateButtons() {
if isStarted {
speakButton.isEnabled = false
stopButton.isEnabled = true
} else {
stopButton.isEnabled = false
speakButton.isEnabled = true
}
}
func voiceNameForIdentifier(identifier: NSSpeechSynthesizer.VoiceName) -> String? {
let attributes = NSSpeechSynthesizer.attributes(forVoice: identifier)
return attributes[NSSpeechSynthesizer.VoiceAttributeKey.name] as? String
}
// MARK: - NSSpeechSynthesizerDelegate
func speechSynthesizer(_ sender: NSSpeechSynthesizer,
didFinishSpeaking finishedSpeaking: Bool){
isStarted = false
print("finishedSpeaking = \(finishedSpeaking)")
}
// MARK: - NSWindowDelegate
func windowShouldClose(sender: AnyObject) -> Bool {
return !isStarted
}
// MARK: - NSTableViewDataSource
func numberOfRows(in tableView: NSTableView) -> Int {
return voices.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
let voice = voices[row]
let voiceName = voiceNameForIdentifier( identifier: voice)
return voiceName as AnyObject?
}
// MARK: - NSTableViewDelegate
func tableViewSelectionDidChange(_ notification: Notification) {
let row = tableView.selectedRow
if row == -1 {
speechSynth.setVoice(nil)
return
}
let voice = voices[row]
speechSynth.setVoice(voice)
}
}