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
    }
}