Record and Playback Audio in iOS

On my last iPad project we needed the ability to record a sound clip and then play it back to the user with some visualizations. This is relatively easy with AVFoundation, but – as with many things in iOS – it takes quite a bit of boilerplate code to get it working.

Recording

To get started, make sure you add the AVFoundation framework to your linked libraries. In XCode, go to your project target -> Build Phases -> Link Binary with Libraries.

We’re going to need to create an audio session, create a file to write to and finally create the recorder with the settings we want.

- (BOOL)startAudioSession
{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *err = nil;
    [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
    if(err){
        NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        return NO;
    }
    
    [audioSession setActive:YES error:&err];
    err = nil;
    if(err){
        NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
        return NO;
    }
    
    BOOL audioHWAvailable = audioSession.inputAvailable;
    if (! audioHWAvailable) {
        NSLog(@"Audio input hardware not available");
        return NO;
    }
    
    return YES;
}

As you can see we don’t need to actually use the audio session for anything, we just need to tell the device that we want to do a recording. In this case I’m just returning a boolean to indicate to the caller that the session was successfully started.

Now we need to create a temporary file to write to.

- (NSURL *)createDatedRecordingFile
{
    NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
    NSString *caldate = [now description];
    NSString *recorderFilePath = [NSString stringWithFormat:@"%@/%@.m4a", [NSHomeDirectory() stringByAppendingPathComponent:@"tmp"], caldate];
    return [NSURL fileURLWithPath:recorderFilePath];
}

Now we can go ahead and create the recorder.

NSError *err = nil;
self.recorder = [[ AVAudioRecorder alloc] initWithURL:self.createDatedRecordingFile settings:self.recordSettings error:&err];
if(!self.recorder){
    NSLog(@"Could not create recorder: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    return;
}

[self.recorder prepareToRecord];
[self.recorder record];

The recording settings here allow you to set various parameters such as the sampling rate and the number of channels. These values heavily influence the size and quality of the audio file you produce, so your specific requirements with dictate what you choose here.

As you can see, it’s mostly just a large amount of boilerplate code.

Playback

The playback is much easier. We simply need to point an AVAudioPlayer at the file we just recorded to and tell it to play.

self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.currentRecording error:nil];
[self.player play];

Full example

My code example is available on GitHub. Happy coding.