ios: how to detect if voice dictation was used for UITextView? Or microphone button was tapped on keyboard

2.4k Views Asked by At

how to detect if voice dictation was used for UITextView? Or microphone button was tapped on keyboard in UI textview

enter image description here

2

There are 2 best solutions below

1
On

You can use Speech Kit framework which Siri uses for speech recognition. first import speech kit framework then and confirm a delegate here is swift version. It may be helpful

    import Speech

    class ViewController: UIViewController, SFSpeechRecognizerDelegate {

     private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
     private var recognitionTask: SFSpeechRecognitionTask?
     private let audioEngine = AVAudioEngine()

     private let speechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "en-US")) 

      override func viewDidLoad() {
        super.viewDidLoad()
        self.authorizeSpeech()
      }

      private func authorizeSpeech() {
        SFSpeechRecognizer.requestAuthorization { (authStatus) in  //4

         var isButtonEnabled = false

         switch authStatus {  //5
          case .authorized:
            isButtonEnabled = true

          case .denied:
           isButtonEnabled = false
           print("User denied access to speech recognition")

          case .restricted:
           isButtonEnabled = false
           print("Speech recognition restricted on this device")

         case .notDetermined:
          isButtonEnabled = false
          print("Speech recognition not yet authorized")
         }

         OperationQueue.main.addOperation() {
            print(isButtonEnabled) //this tells that speech authorized or not
         }
       }
      }


    }

now add some custom message in you info.plist

   <key>NSMicrophoneUsageDescription</key>  <string>Your microphone will be used to record your speech when you press the Start Recording button.</string>

    <key>NSSpeechRecognitionUsageDescription</key>  <string>Speech recognition will be used to determine which words you speak into this device microphone.</string>

now create a new function called startRecording()

func startRecording() {

if recognitionTask != nil {
    recognitionTask?.cancel()
    recognitionTask = nil
}

let audioSession = AVAudioSession.sharedInstance()
do {
    try audioSession.setCategory(AVAudioSessionCategoryRecord)
    try audioSession.setMode(AVAudioSessionModeMeasurement)
    try audioSession.setActive(true, with: .notifyOthersOnDeactivation)
} catch {
    print("audioSession properties weren't set because of an error.")
}

recognitionRequest = SFSpeechAudioBufferRecognitionRequest()

guard let inputNode = audioEngine.inputNode else {
    fatalError("Audio engine has no input node")
}

guard let recognitionRequest = recognitionRequest else {
    fatalError("Unable to create an SFSpeechAudioBufferRecognitionRequest object")
}

recognitionRequest.shouldReportPartialResults = true

recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in

    var isFinal = false

    if result != nil {

        your_text_view.text = result?.bestTranscription.formattedString
        isFinal = (result?.isFinal)!
    }

    if error != nil || isFinal {
        self.audioEngine.stop()
        inputNode.removeTap(onBus: 0)

        self.recognitionRequest = nil
        self.recognitionTask = nil


    }
})

let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
    self.recognitionRequest?.append(buffer)
}

audioEngine.prepare()

do {
    try audioEngine.start()
} catch {
    print("audioEngine couldn't start because of an error.")
}

}

confirm delegate

    func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) {
     if available {
        startRecording()
     } else {
      //print("not implement")
     }
    }
0
On

If you are searching this for hiding label placeholder, below one will help you.

public func textViewDidChange(_ textView: UITextView) {
    if (textView.text?.isEmpty)! {
        lblPlaceholder?.isHidden = false
    } else {
        lblPlaceholder?.isHidden = true
    }
}