Record audio in iOS Swift

Vikas Kore
3 min readFeb 14, 2019

--

In this story we will cover to do’s for recording audio in iOS Swift 4.2. Developers have to test this demo on device only, because as we know the hardware features that cannot be simulated are:
Accelerometer
Gyroscope
Camera
Proximity Sensor
Microphone Input

To know more about simulator use and limitation visit this link: https://help.apple.com/simulator/mac/current/#/

For recording video we have to import “AVFoundation” framework and use his delegates and dataSource Methods to catch Record, Play, Finish and Errors events.

To overview iOS frameworks please visit this link

if you just have to play a audio from url on button click then check this

Before start coding simply take 2 buttons on viewController in storyboard

1. Record button: for recording (optional title: “Tap to record”)
2. Play Button: for Play and Stop recording (optional title: “Play”)

In your .swift file create variable of type AVAudioSession, AVAudioRecorder, AVAudioPlayer to start recording session, recorder instance and to play recorded audio respectively.

Then setup audio recorder

func setupView() {
recordingSession = AVAudioSession.sharedInstance()
do {
try recordingSession.setCategory(.playAndRecord, mode: .default)
try recordingSession.setActive(true)
recordingSession.requestRecordPermission() { [unowned self] allowed inDispatchQueue.main.async {if allowed {self.loadRecordingUI()} else {// failed to record}}}} catch { // failed to record }}func loadRecordingUI() {
recordButton.isEnabled = true
playButton.isEnabled = false
recordButton.setTitle("Tap to Record", for: .normal)
recordButton.addTarget(self, action: #selector(recordAudioButtonTapped), for: .touchUpInside)view.addSubview(recordButton)}

func loadRecordingUI() is just to enable record button after recorder ready and disable play button until record a sound/audio

To start recording audio first we have to get path/location to save recorded file, set audio format, rateKey, channelKey and quality

func startRecording() {let audioFilename = getFileURL()let settings = [AVFormatIDKey: Int(kAudioFormatMPEG4AAC),AVSampleRateKey: 12000,AVNumberOfChannelsKey: 1,AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue]do {audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)audioRecorder.delegate = selfaudioRecorder.record()recordButton.setTitle("Tap to Stop", for: .normal)playButton.isEnabled = false} catch {finishRecording(success: false)}}

And to finish recording we just have to stop audioRecoder and assign nil to the object for future recording and change status & title of Record and play button

func finishRecording(success: Bool) {audioRecorder.stop()
audioRecorder = nil
if success {
recordButton.setTitle("Tap to Re-record", for: .normal)
} else {
recordButton.setTitle("Tap to Record", for: .normal)// recording failed}playButton.isEnabled = true
recordButton.isEnabled = true
}

To play the recording on play button click we have to get url/location of saved audio and call audioPlayer.play()

@IBAction func playAudioButtonTapped(_ sender: UIButton) {if (sender.titleLabel?.text == "Play"){recordButton.isEnabled = falsesender.setTitle("Stop", for: .normal)preparePlayer()audioPlayer.play()} else {audioPlayer.stop()sender.setTitle("Play", for: .normal)}}func preparePlayer() {var error: NSError?do {audioPlayer = try AVAudioPlayer(contentsOf: getFileURL() as URL)} catch let error1 as NSError {error = error1audioPlayer = nil}if let err = error {print("AVAudioPlayer error: \(err.localizedDescription)")} else {
audioPlayer.delegate = self
audioPlayer.prepareToPlay()audioPlayer.volume = 10.0}}

To save and get path of audio

func getDocumentsDirectory() -> URL {let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)return paths[0]}func getFileURL() -> URL {let path = getDocumentsDirectory().appendingPathComponent("recording.m4a")return path as URL}

if you want to stop recording after some time then best way to use

DispatchQueue.main.asyncAfter(deadline: .now() + TimeToRecordGoesHere) {
finishRecording(success: true)
}

Full source code available here: https://gist.github.com/vikaskore/e5d9fc91feac455d6b4778b3d768a6e8

Thank you, Happy coding!

--

--