Objective c NSSpeechRecognizer和.delegate=self;问题
我在做这件事时遇到了一个问题,事实证明这是一个障碍。我在El Capitan上玩苹果的Objective c NSSpeechRecognizer和.delegate=self;问题,objective-c,macos,speech-recognition,osx-elcapitan,appkit,Objective C,Macos,Speech Recognition,Osx Elcapitan,Appkit,我在做这件事时遇到了一个问题,事实证明这是一个障碍。我在El Capitan上玩苹果的NSSpeechRecognitizer软件,我试图让这个家伙正常运行,这样当我给它的谜语呈现给用户时,用户可以用一个词来回应“做些酷的事”。目前,委托方法: -(void) speechRecognizer:(NSSpeechRecognizer *)sender didRecognizeCommand:(NSString *)command { ... }` 即使识别图标似乎正确地检测到谜语的答案,也从未
NSSpeechRecognitizer
软件,我试图让这个家伙正常运行,这样当我给它的谜语呈现给用户时,用户可以用一个词来回应“做些酷的事”。目前,委托方法:
-(void) speechRecognizer:(NSSpeechRecognizer *)sender didRecognizeCommand:(NSString *)command { ... }`
即使识别图标似乎正确地检测到谜语的答案,也从未调用。问题在于您的
main
函数有一个循环,不断检查语音是否已被识别。您没有给NSSpeechRecognizer
一个向您实际发送任何消息的机会
你的应用程序需要让主“运行循环”运行,这样它才能传递消息。通常,在OSX应用程序中,您的main
只需调用NSApplicationMain
,它就会为您执行此操作
您的代码实际上是这样的:
@interface RecognizerDelegate : NSObject <NSSpeechRecognizerDelegate>
@property (nonatomic) NSSpeechRecognizer *recognizer;
@property (nonatomic) BOOL didRecognize;
@end
@implementation RecognizerDelegate
- (id)init
{
if ((self = [super init])) {
self.didRecognize = NO;
self.recognizer = [[NSSpeechRecognizer alloc] init];
self.recognizer.listensInForegroundOnly = NO;
self.recognizer.blocksOtherRecognizers = YES;
self.recognizer.delegate = self;
self.recognizer.commands = @[ @"hello" ];
[self.recognizer startListening];
}
return self;
}
- (void)speechRecognizer:(NSSpeechRecognizer *)sender didRecognizeCommand:(NSString *)command
{
self.didRecognize = YES;
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool
{
RecognizerDelegate *recognizerDelegate = [[RecognizerDelegate alloc] init];
while (recognizerDelegate.didRecognize == NO) {
// do nothing
}
NSLog(@"Recognized!");
}
return 0;
}
长期的解决办法是将代码移出main
,并像真正的OSX应用程序一样构建它。与使用循环轮询条件(如recognizerDelegate.didRecognite
)不同,您可以直接从委托方法(如-speechRecognizer:didRecognitizeCommand:
)触发“下一件事”,或者使用NSTimer
定期运行代码
有关更多详细信息,请参阅Apple文档,特别是“主事件循环”部分。我在使用NSSpeechRecognizer时遇到了同样的问题。回调函数:
func speechRecognizer(_ sender: NSSpeechRecognizer,
didRecognizeCommand command: String) {}
…从未被呼叫过,尽管一切似乎都在运行
为了让代码正常工作,我改变了三件事
1) 我必须在我的“沙盒”模式应用程序中启用授权,以允许使用麦克风
。。。我也做了另外两件事
2) 我在info.pList中添加了“隐私-麦克风使用说明”,并将字符串值设置为“我想听你说话”
3) 我在info.pList中添加了“Privacy-Speech Recognition Usage Description”,并将字符串值设置为“I want down what you say”请在问题中包含代码的相关部分。在您链接到的github存储库中,我没有看到任何使用
NSSpeechRecognizer
的内容。(唯一的代码是main.m,它直接来自Xcode模板。)你完全正确。很抱歉。哇,非常感谢你的详细解释。我真的需要更清楚地了解运行循环内部的存在是如何影响对象的。我想我的下一步是学习如何重新组织一切,这样我就可以简单地返回NSApplicationMain(…)代码>主菜单的内部。我希望能够做到这一点,而不必依赖XCode为我设置它(在vim内部,如果更好的话:P),这就是为什么我首先遇到这个问题的原因!无论如何-谢谢你,现在一切都很好。@DavidLewis:太好了!由于您发现此答案很有用,请单击答案旁边的复选标记。
func speechRecognizer(_ sender: NSSpeechRecognizer,
didRecognizeCommand command: String) {}