我是Swift
和OS X
编程的新手。我正在尝试使用进度监视器来指示我的语音合成器说话文本的进度。
let speechSynthesizer = NSSpeechSynthesizer()
speechSynthesizer.delegate = self;
speechSynthesizer.startSpeakingString(contents)
我想设置
progressIndicator.maxValue = Double(NSSpeechStatusNumberOfCharactersLeft.characters.count)
然后使用NSSpeechStatusNumberOfCharactersLeft定期更新progressIndicator,根据Apple的文档,该值应为0。
我尝试访问此密钥的每一种方式都返回相同的不准确数字,所以我显然没有正确使用它。我找到的唯一例子是Objective-C
NSNumber *n = [[self.speechSynth objectForProperty:NSSpeechStatusProperty error:NULL] objectForKey:NSSpeechStatusNumberOfCharactersLeft];
我尝试将其翻译为Swift
,但仍然没有骰子。
let count = try speechSynthesizer.objectForProperty(NSSpeechStatusProperty).objectForKey(NSSpeechStatusNumberOfCharactersLeft)
我也试过
speechSynthesizer.valueForKey(NSSpeechStatusNumberOfCharactersLeft))
speechSynthesizer.valueWithName(NSSpeechStatusNumberOfCharactersLeft, inPropertyWithKey: NSSpeechStatusProperty))
抛出运行时异常。有什么想法吗?提前谢谢!
答案 0 :(得分:1)
你的第二次尝试非常接近正确:
let count = try speechSynthesizer.objectForProperty(NSSpeechStatusProperty).objectForKey(NSSpeechStatusNumberOfCharactersLeft)
没有错误消息(因为我没有方便的Swift 2编译器)我猜测失败的原因是objectForProperty
的返回值不知道是字典,所以你不能在其中查找值。
这是我的快速&脏Swift 3游乐场测试这个:
import PlaygroundSupport
import Cocoa
let synth = NSSpeechSynthesizer()
synth.startSpeaking("I'm not standing still, I am lying in wait")
// quick way to test for progress without setting up an app and delegate
PlaygroundPage.current.needsIndefiniteExecution = true
let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
let statusDict = try! synth.object(forProperty: NSSpeechStatusProperty) as! [String: Any]
print(statusDict[NSSpeechStatusNumberOfCharactersLeft])
}
(显然,如果您在具有合成器代表的应用程序中运行此功能,则不需要所有计时器内容或游乐场业务。)
关键位(没有双关语)是转换objectForProperty
的返回值,以便Swift知道它是一个字典,然后查找该字典中的字符数。
现在,这段代码运行正常,但它并不完全适用于设置进度条 - 当合成器完成发言时,NSSpeechStatusNumberOfCharactersLeft
可能是一些非零值。 (在这种情况下,另一个状态键NSSpeechStatusOutputBusy
将变为false
。)因此,您的进度条将达不到100%,您可以使用NSSpeechStatusOutputBusy
键或代理didFinishSpeaking
回调以完成剩下的任务,删除进度用户界面等等。