0

This might seem like a really basic question but I'm struggling to find the answer. As far as I'm aware AVAudioInputNode has been available since iOS 8 and it can be used to record from the microphone on an iPhone for example.

I know previously I would use AVAudioRecorderSession to request permission to record and inspect if I had permission etc. What I'm struggling with is seeing how to request and check permission when using AVAudioEngine.

So in something like the below, how would I go about doing this?

import AVFoundation

class ViewController: UIViewController {
    let audioEngine = AVAudioEngine()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func recordPressed(sender:AnyObject) {
        try! startRecording()
    }

    func startRecording() throws{
        let audioSession = AVAudioSession.sharedInstance()
        try audioSession.setCategory(AVAudioSessionCategoryRecord)
        try audioSession.setMode(AVAudioSessionModeMeasurement)
        try audioSession.setActive(true, withOptions: .NotifyOthersOnDeactivation)

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

        let recordingFormat = inputNode.outputFormatForBus(0)

        inputNode.installTapOnBus(0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in

        }

        audioEngine.prepare()

        try audioEngine.start()


    }

}

I've noticed that the microphone privacy message can be set in the plist and calling audioEngine.inputNode seems to present this message. But I still can't see where to check if that permission has been granted. If I add

   if (audioSession.recordPermission() == AVAudioSessionRecordPermission.granted){

    }else{
        print("No permission")
    }

directly after the guard let inputNode line it presents the message but always tells me that permission isn't granted before I've even responded to the alert.

What's the best way to go about this? Should I just fall back to using the audioSession methods first? For what it's worth a lot of this was lifted from the WWDC code around speechRecognizer. I just can't see where they are handling the mic permission

In fact it doesn't always seem to present the alert to request permissions. What am I missing here as the examples I've found seem to skip this permission step

TommyBs
  • 9,354
  • 4
  • 34
  • 65

1 Answers1

0

Ok so looking the docs I found this:

Recording audio requires explicit permission from the user. The first time your app’s audio session attempts to use an audio input route while using a category that enables recording, the system automatically prompts the user for permission. You can explicitly ask earlier by calling this method. Until the user grants your app permission to record, your app can record only silence.

This method always returns immediately, but the response block awaits user input if the user has not previously granted or denied permission to record in your app.

When a user responds to a recording permission prompt for your app, the system remembers the choice. If the user has denied recording permission, they can reenable it in Settings > Privacy > Microphone.

So it looks like it's doing it automatically when first trying to use the microphone, but ideally I should ask this permission upfront

TommyBs
  • 9,354
  • 4
  • 34
  • 65