NSSpeechRecognizer и.delegate=self; Проблемы

Я столкнулся с проблемой с этим небольшим проектом Objective-C, который я делаю, и он оказывается немного препятствием. Я играю с Apple NSSpeechRecognizer на El Capitan, и я пытаюсь заставить этого парня работать должным образом, чтобы, когда загадка, которую я даю, была задана пользователю, пользователь мог ответить словом "сделать что-то крутое". В нынешнем виде метод делегата:

-(void) speechRecognizer:(NSSpeechRecognizer *)sender didRecognizeCommand:(NSString *)command { ... }`

даже никогда не вызывается, даже если кажется, что значок распознавания правильно определяет ответ на загадку.

2 ответа

Решение

Проблема в том, что ваш main Функция имеет цикл, который постоянно проверяет, распознает ли речь. Вы не даете NSSpeechRecognizer возможность на самом деле доставить вам любые сообщения.

Ваше приложение должно запускать основной цикл выполнения, чтобы оно могло доставлять сообщения. Обычно в приложении OS X ваш 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;
}

Тот while цикл не делает ничего полезного, просто работает ваш процессор в цикле и тратит время и энергию. Вы не позволяете любой другой код в NSSpeechSynthesizerили любой из системных платформ, таких как Foundation или AppKit, получите возможность сделать что-нибудь. Итак, ничего не происходит.

Чтобы исправить это в краткосрочной перспективе: вы можете позволить основному циклу выполнения работать некоторое время при каждом проходе цикла. Этот код позволит системе работать на секунду, а затем вернется к вашему коду, чтобы вы могли проверить снова:

while (recognizerDelegate.didRecognize == NO) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
}

Более долгосрочным решением было бы убрать ваш код из main и структурировать его как настоящее приложение OS X. Вместо того, чтобы использовать цикл для опроса условия как recognizerDelegate.didRecognize, вы просто вызвали бы "следующую вещь" непосредственно из методов делегата, таких как -speechRecognizer:didRecognizeCommand:или вы бы использовали такие вещи, как NSTimer периодически запускать код.

Для получения дополнительной информации посмотрите Apple Doc Cocoa Application Competencies для OS X, в частности, раздел "Основной цикл событий".

У меня была такая же проблема с использованием NSSpeechRecognizer. Функция обратного вызова:

func speechRecognizer(_ sender: NSSpeechRecognizer,
                      didRecognizeCommand command: String) {}

... никогда не звонили, хотя казалось, что все работает.

Я изменил три вещи, чтобы заставить код работать.

1) Я должен был включить разрешение в своем приложении "песочница", чтобы использовать микрофон.

... Я также сделал эти две другие вещи, а также.

2) Я добавил "Конфиденциальность - описание использования микрофона" в info.pList и установил строковое значение "Я хочу слушать вашу речь"

3) Я добавил "Конфиденциальность - описание использования распознавания речи" в info.pList и установил строковое значение "Я хочу записать то, что вы говорите"

Другие вопросы по тегам