Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何检测正在进行的语音识别 问题:_Ios_Uitextfield_Speech To Text - Fatal编程技术网

Ios 如何检测正在进行的语音识别 问题:

Ios 如何检测正在进行的语音识别 问题:,ios,uitextfield,speech-to-text,Ios,Uitextfield,Speech To Text,我有UITextField和带有发送功能的ui按钮。当用户按下发送按钮时,我正在执行简单的操作: - (IBAction)sendMessage: (id)sender { [self.chatService sendMessage: self.messageTextField.text]; self.messageTextField.text = @""; // here I get exception } 现在,当用户从键盘开始使用听写,然后在听写视图(键盘)上按“完成”,并立

我有
UITextField
和带有发送功能的
ui按钮。当用户按下发送按钮时,我正在执行简单的操作:

- (IBAction)sendMessage: (id)sender {
   [self.chatService sendMessage: self.messageTextField.text];
   self.messageTextField.text = @""; // here I get exception
}
现在,当用户从键盘开始使用听写,然后在听写视图(键盘)上按“完成”,并立即按“发送”按钮时,出现异常“范围或索引超出范围”

可能的解决办法: 我注意到,当语音识别服务器处理数据时,其他应用程序会禁用此“发送”按钮。这正好在两个事件之间:用户按“完成”,结果显示在文本字段中。我希望以同样的方式解决这个问题

我在文档中发现可以收到此通知的地方有问题。我已经找到了<代码>输出<代码>协议,但这不是我需要的

类似主题:
  • -解决方案不可接受(可能被苹果拒绝)
  • -与上述方法类似
我试过什么:
  • 只需捕获并忽略异常。崩溃并没有加剧,但虚拟键盘变得完全无响应
  • [UITEPUTMODE currentInputMode].主语言
    等于
    @“听写”
    时禁用发送按钮。通知
    UITEMPUTCurrentInputModeDidChangeNotification
    ,它报告听写服务提交新值之前听写模式的结束,我仍然能够单击发送按钮导致异常。我可以在
    primaryLanguage
    丢失@“听写”值时添加延迟,但我不喜欢这种方法。最可能的情况是,所需的延迟取决于语音识别服务的响应程度
  • 我已经在不同的事件上添加了一系列操作(此事件看起来正在处理:
    uicontroleventeditingdidbeagin
    UIControlEventEditingChanged
    uicontroleventeditingdidebend
    uicontroleventeditingdidenonexit
    )。好的是,它看起来像是在所需的时刻触发
    UIControlEventEditingChanged
    :当用户在口述视图上按“完成”时,以及当服务提交或结束口述时。这是我到目前为止最好的概念。不好的地方是,在其他情况下也会触发此控件,并且没有信息来区分在哪种情况下触发了此控件事件,因此我不知道应该禁用或启用按钮,还是什么都不做
  • 我终于找到了最终的解决办法。 它简单优雅,将通过苹果公司的审查,并始终有效。只需对
    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;
    }
    

    老办法 芬利,我找到了一些解决办法。这是改进的概念nr 3与概念nr 2的混合(基于)

    现在问题并没有出现,因为用户在可能发生的情况下被阻止(恰好在用户按下听写视图上的“完成”按钮和语音识别服务的结果之间)。

    好的是使用了公共API(只有@“听写”可能是个问题,但我认为苹果应该接受它)。

    在iOS 7中,苹果引入了TextKit,因此有了关于这个问题的新信息: NSAttachmentCharacter=0xfffc 用于表示附件,如所述


    因此,如果您的版本大于或等于7.0,更好的方法是检查attributedString的附件。

    您的备注部分指出,UITestInputCurrentInputModeDidChangeNotification失败是因为报告结束时间太早。如果您使用这种方法,但在输入模式从“听写”更改回时会怎么样,以0.0延迟执行performSelector以清除文本。通知可能在SDK中被阻止。也许您只需要延迟到运行循环的下一轮?是的,我考虑过这一点。我不喜欢它(请参阅编辑),但似乎是唯一的解决方案。也许你可以通过GCD将呼叫提交到主队列,而不是延迟performSelector?这可能会在听写完成后将其放入队列,而不会遭受推测性延迟。是的,如果你需要延迟,比如N秒,那么我同意这是自找麻烦,因为你有所有竞争条件和延迟可能太长,或者有时会导致崩溃。但我建议0.0延迟,只是为了让您的消息排在后面。如果这一切都有效,我认为它将可靠地工作,就像我在编辑中写的,这个测试用例已经提供了这种延迟(用户必须执行两个操作,第一个操作更改
    primaryLanguage
    ),因此零延迟不是解决方案。这不是这个问题的答案,更像是对我的答案的改进意见。无论如何,谢谢。这个常量需要使用复杂的API(
    NSCharacterSet
    NSRange
    ),我更喜欢使用字符串文字,它更简单。您好,Marek,您在最终解决方案中遇到任何问题吗?您是否在生产应用程序中运行此代码?应用程序已经在app store中,我没有看到任何新的错误,但是!应用程序不再受支持(客户决定推出新的更高级的产品),所以我没有任何新的错误报告。它应该在所有情况下都能工作,除非你在文本中添加了一些图形(例如表情符号),如果你这样做了,那么检测逻辑必须更加复杂(检测的基础是语音识别通过在文本中临时添加图标来表示工作进度,并且通过替换字符在文本中标记evry图标/图形)。您的新方法在iOS 9中不再有效。为
    uicontrol事件添加目标的旧方法。编辑已更改,然后检查
    sender.textInputMode?。primaryLanguage==“口述”
    确实有效。虽然还没有通过审查,但我不明白为什么会出现问题。至少修复了在iOS 8语音识别过程中修改文本时可能发生的崩溃。这就是我需要此解决方案的原因。
    -(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 ...