简体   繁体   English

如何检测语音识别正在进行中

[英]How to detect that speech recogntion is in progress

Problem: 问题:

I have UITextField side by side with UIButton with send functionality. 我有UITextFieldUIButton并排发送功能。 When user presses send button I'm performing simple action: 当用户按下发送按钮时,我正在执行简单的操作:

- (IBAction)sendMessage: (id)sender {
   [self.chatService sendMessage: self.messageTextField.text];
   self.messageTextField.text = @""; // here I get exception
}

Now when user starts using dictation from keyboard, then presses done on dictation view (keyboard) and immediately presses send button, I've got exception "Range or index out of bounds". 现在,当用户从键盘开始使用听写时,然后按下听写视图(键盘)并立即按下发送按钮,我有异常“范围或索引越界”。

Possible solution: 可能的方法:

I've noticed that other applications disable this "send" button when speech recognition server is processing data. 我注意到,当语音识别服务器处理数据时,其他应用程序会禁用此“发送”按钮。 This is exactly between two events: user presses "done" and results are appearing in text field. 这恰好在两个事件之间:用户按下“完成”,结果出现在文本字段中。 I wish to solve it in the same manner. 我希望以同样的方式解决它。

I've problem finding in documentation where this notification can be received. 我在文档中找到可以收到此通知的问题。 I've found UITextInput protocol, but this is not what I need. 我找到了UITextInput协议,但这不是我需要的。

Similar topics: 类似主题:

What have I tried: 我试过了什么:

  1. simply catch and ignore exception. 简单地捕捉并忽略异常。 Crash didn't acured, but virtual keyboard become completely unresponsive 崩溃没有确定,但虚拟键盘变得完全没有反应
  2. Disabling send button when [UITextInputMode currentInputMode].primaryLanguage is equal @"dictation" . [UITextInputMode currentInputMode].primaryLanguage等于@"dictation"时禁用发送按钮。 Notification UITextInputCurrentInputModeDidChangeNotification which reports end of dictation mode arrives before dictation service commits new value and I'm still able to click send button to cause exception. 在听写服务提交新值之前报告听写结束模式的通知UITextInputCurrentInputModeDidChangeNotification到达,我仍然可以点击发送按钮导致异常。 I could add delay when primaryLanguage losses @"dictation" value, but I don't like this approach. primaryLanguage损失@“听写”值时,我可以增加延迟,但我不喜欢这种方法。 Most probably this required delay depends how much speech recognition service is responsive. 最可能的是,这种所需的延迟取决于语音识别服务的响应程度。
  3. I've added bunch of actions on different events (this evets was looking processing: UIControlEventEditingDidBegin , UIControlEventEditingChanged , UIControlEventEditingDidEnd , UIControlEventEditingDidEndOnExit ). 我在不同的事件上添加了大量的操作(这个evets正在寻找处理: UIControlEventEditingDidBeginUIControlEventEditingChangedUIControlEventEditingDidEndUIControlEventEditingDidEndOnExit )。 The good thing is that it looks like UIControlEventEditingChanged is fired exactly at desired moments: when user presses "Done" on dictation view and when service is committing or ending dictation. 好处是看起来UIControlEventEditingChanged在所需的时刻完全被触发:当用户在听写视图上按“完成”并且服务提交或结束听写时。 So this is my best concept so far. 所以这是我迄今为止最好的概念。 The bad thing is that this is fired in other cases too and there is no information to distinguish in which case this control event was fired, so I don't know should I disable or enable the button or do nothing. 不好的是,在其他情况下这也被解雇了,并且没有信息可以区分这种控制事件被触发的情况,所以我不知道应该禁用或启用按钮或什么也不做。

I finally found ultimate solution. 我终于找到了终极解决方案

It is simple elegant will pass apple review and it Always work. 它简单优雅将通过苹果审查,它始终工作。 Just react on UIControlEventEditingChanged and detect existance of replacemnt characterlike this: 只需对UIControlEventEditingChanged做出反应,并检测出替换类型的存在,如下所示:

-(void)viewDidLoad {
  [super viewDidLoad];

  [self.textField addTarget: self
                     action: @selector(eventEditingChanged:)
           forControlEvents: UIControlEventEditingChanged];
}

-(IBAction)eventEditingChanged:(UITextField *)sender {
  NSRange range = [sender.text rangeOfString: @"\uFFFC"];
  self.sendButton.enabled = range.location==NSNotFound;
}


Old approach 老方法

Finlay I've found some solution. Finlay我找到了一些解决方案。 This is improved concept nr 3 with mix of concept nr 2 (based on that answer ). 这是改进的概念nr 3与概念nr 2的混合(基于该答案 )。

-(void)viewDidLoad {
  [super viewDidLoad];

  [self.textField addTarget: self
                     action: @selector(eventEditingChanged:)
           forControlEvents: UIControlEventEditingChanged];
}

-(IBAction)eventEditingChanged:(UITextField *)sender {
  NSString *primaryLanguage = [UITextInputMode currentInputMode].primaryLanguage;

  if ([primaryLanguage isEqualToString: @"dictation"]) {
    self.sendButton.enabled = NO;
  } else {
    // restore normal text field state
    self.sendButton.enabled = self.textField.text.length>0;
  }
}

- (IBAction)sendMessage: (id)sender {
   [self.chatService sendMessage: self.messageTextField.text];
   self.messageTextField.text = @"";
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
  if (self.textField.text.length==0 || !self.sendButton.enabled) {
     return NO;
   }
   [self sendMessage: textField];
   return YES;
}

// other UITextFieldDelegate methods ...

Now problem doesn't appears since user is blocked when it could happen (exactly between user presses "Done" button on dictation view and when results are coming from speech recognition service. 现在问题没有出现,因为用户在可能发生时被阻止(恰好在用户按下听写视图上的“完成”按钮和结果来自语音识别服务之间。
The good thing is that public API is used (only @"dictation" can be a problem, but I thin it should be accepted by Apple). 好处是使用公共API(只有@“听写”可能是一个问题,但我认为它应该被Apple接受)。

In iOS 7 Apple introduced TextKit so there are new information for this question: NSAttachmentCharacter = 0xfffc Used to denote an attachment as documentation says. 在iOS 7中,Apple引入了TextKit,因此有关于此问题的新信息: NSAttachmentCharacter = 0xfffc用于表示附件,如文档所述

So, if your version is more or equal to 7.0 , better approach is to check attributedString for attachments. 因此,如果您的版本大于或等于7.0 ,更好的方法是检查referencedString的附件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM