AVFoundation audio recording with Swift

Swift Language

Swift AVFoundation Recorder

Use AVFoundation to create an audio recording.

Introduction

AVFoundation makes audio recording a lot simpler than recording using Core Audio. Essentially, you simply configure and create an AVAudioRecorder instance, and tell it to record/stop in actions.

Creating a Recorder

The first thing you need to do when creating a recorder is to specify the audio format that the recorder will use. This is a Dictionary of settings. For the AVFormatIDKey there are several
predefined Core Audio data format identifiers such as kAudioFormatLinearPCM and kAudioFormatAC3. Here are a few settings to record in Apple Lossless format.

Then you create the recorder with those settings and the URL of the output sound file. If the recorder is created successfully, you can then call prepareToRecord() which will create or overwrite the sound file at the specified URL. If you’re going to write a VU meter style graph, you can tell the recorder to meter the recording. You’ll have to install a timer to periodically ask the recorder for the values. (See the github project).

Swift 1:

Or in Swift 2:

Table of Contents

Recorder Delegate

I set the recorder’s delegate in order to be notified that the recorder has stopped recording. At this point you can update the UI (e.g. enable a disabled play button) and/or prompt the user to keep or discard the recording. In this example I use the new iOS 8 UIAlertController class. If the user says “delete the recording”, simply call deleteRecording() on the recorder instance.

Table of Contents

Recording

In order to record, you need to ask the user for permission to record first. The AVAudioSession class has a requestRecordPermission() function to which you provide a closure. If granted, you set the session’s category to AVAudioSessionCategoryPlayAndRecord, set up the recorder as described above, and install a timer if you want to check the metering levels.

Here is a very simple function to display the metering level to stdout, as well as displaying the current recording time. Yes, string formatting is awkward in Swift. Have a better way? Let me know.

Table of Contents

Summary

That’s it. You now have an audio recording that you can play back using an AVAudioPlayer instance.

Resources

31 thoughts on “AVFoundation audio recording with Swift”

  1. Hi Gene,

    Thanks for the awesome resource on Swift audio.

    I’m (very much) a beginner in iOS development, and I would love to learn how to create an app that would have some basic audio functionalities.

    I was hoping to learn a bit by taking a look at your example project which I downloaded from GitHub.

    Unfortunately I cannot build/run it, I get a bunch of errors http://cl.ly/image/2V2P1b0b0q2V

    Could you help me out by pointing out to anything I might be missing?

    Thanks!

    1. Ah, thanks.

      I looked at your image and saw that it was just that the code was for a Swift beta.

      I’ve updated the code to Swift 1.0 and pushed it to the github repo.

      Do a pull and you should be good to go.

  2. Hi, I noticed that this code only works on the simulator, and not the device. Any advice on how to get it to work on the iPhone 6? I believe the line “if !session.setActive(true, error: &error)” is causing the compiler error. Please let me know if you figure this out, thank you.

    1. I just tried it on my iPhone 4S and iPad 2 and it works on both devices.
      Do a git pull to make sure you have the latest.
      I don’t have an iPhone 6. Could you send me a stack dump? I really hope there isn’t a version thing to check.

      1. Very good work
        it works only on the simulator not on my iPhone i have the error message :
        No provisioning profiles with a valid signing identity (i.e. certificate and private key pair) matching the bundle identifier “com.rockhoppertech.AVFoundation-Recorder” were found.

        Xcode can attempt to fix this issue. This will reset your code signing and provisioning settings to recommended values and resolve issues with signing identities and provisioning profiles.

        could you help me to correct it please ?
        another question: i want to save data on a sql server data base, how can i do it please ?
        thanks a lot

        1. That’s my signing identity. Say OK to that dialog or go to project settings and change it to yours. There’s a button there to do this.

    1. I don’t understand. Are you starting with the headphone plugged in and then remove it? If so, you need to handle a route change notification.

  3. Hi,

    I am wondering if you can help me with this question:

    How can I use a Audio file (like sample.mp3) as one input and having a microphone as another input, but doesn’t record on on top of original sample.mp3 and make another .mp3 (like sample2.mp3) which would be recorded voice on top of that music (sample.mp3)

  4. Hi,
    Actually the Code works fine for me, there is one question how can i add an option to email the voice that i record it?

  5. Thx for the resource of recorder, i just started making IOS program by myself and this is very helpful.
    I made one recorder successfully by studying your code, but i believe that my recorder doesn’t work properly. when i run the program, the memory consuming for my recorder is too high. it start with 50mb then increases to 100mb as i recored more. can you tell me what is wrong with it?

  6. Hi, great tutorial!
    Is there a way to cut the recorded file, something like:
    recordedFile.cut(time interval to cut)
    I’m searching for this on the net but i didn’t find anything..
    Thank you very much.

  7. Hey there, I’m so happy founding your blog, this is exactly what I was looking for. (Great job!!)
    I’m trying to write a small challenge-game app, where two people have to blow into the mic. There should be a paper plane on the screen and each player has to “blow” this plane virtual as far as they can.
    Is it possible to measure the meters to determine the winner?
    Thank you in advance 🙂

  8. Hi Gene,
    i found a issue in the code, in viewdidload you call the function “setSessionPlayback()”, but when you press the record button, you call “setSessionPlayAndRecord” overwriting the playback session. So when you press play the recorded audio are so low in volume. To fix this you need to call the setSessionPlayBack when press the play button.

  9. Hi, this is a fantastic tutorial! I’m interested in processing the samples as they are recorded in real-time but I have not had much success with finding a way to do this. Is there maybe some kind of call-back function for this purpose? I’d like to eventually stream the recording to a server for further processing, but the final missing link is accessing the samples as they are recorded.

    1. Astonishing comment from “John” here. “you can just get the full code from this crappy Wix website for $25”.

      My code is on Github for free and this clown thinks it’s ok to repackage it and sell it for $25 AND THEN advertise it here.

      He is my nomination for jerk of the year.

      Send him an email sebastianjuan1994@gmail.com

  10. Hi Gene,
    Thanks for posting this tutorial, your example code was the best I found on internet (and I’ve seen quite a few sites already). I finally understood the right way to create and close sessions for audio processing.
    The only minor thing that I couldn’t make work in the real device is the “setMode” :
    try session.setMode(“AVAudioSessionModeVoiceChat”)
    For some reason it is never able to set mode successfully, other than that everything works perfectly.

  11. Gi Gene

    Fantastic tutorial. Any tips on doing a visual representation of the recording – like a frequency meter

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.