most likely to be a mistake, since the delegate method didCancelSpeechUtterance method is not called after the first statement;
A workaround would be to bind the statements, rather than cast them into an array, and queue them immediately.
Use the didFinishSpeechUtterance delegate synthesis method to increase the pointer to an array and infer the next text from this array. Then, trying to stop the speech, set the BOOL, which is checked in this delegate method, before attempting to pronounce the following text.
For example:
1) implement a protocol in a view controller that performs speech synthesis
#import <UIKit/UIKit.h> @import AVFoundation; @interface ViewController : UIViewController <AVSpeechSynthesizerDelegate> @end
2) create an instance of AVSpeechSynthesizer and set its delegate to self
speechSynthesizer = [AVSpeechSynthesizer new]; speechSynthesizer.delegate = self;
3) use the utterance counter set to zero at the beginning of the conversation
4) use an array of texts to speak
textArray = @[@"Mary had a little lamb, its fleece", @"was white as snow", @"and everywhere that Mary went", @"that sheep was sure to go"];
5) add the delegate didFinishSpeechUtterance method to speak the next statement from an array of texts and increase the statement counter
- (void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{ if(utteranceCounter < utterances.count){ AVSpeechUtterance *utterance = utterances[utteranceCounter]; [synthesizer speakUtterance:utterance]; utteranceCounter++; } }
5) to stop the conversation, set the utterance counter to the array of texts and try to stop the synthesizer
utteranceCounter = utterances.count; BOOL speechStopped = [speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate]; if(!speechStopped){ [speechSynthesizer stopSpeakingAtBoundary:AVSpeechBoundaryWord]; }
6), again, reset the utterance counter with zero