Welcome reader to the part 2 of the tutorial Record and Play Audio tutorial.
Tutorial Revision Notes
|
Today, you will implement these features in the AudioDiary project you worked on last week.
The Recordings view is shown when the app user tap the Recorder View’s navigation button. You’ll add code in the RecordingsViewController.swift class file to enable the app user to perform these tasks:
- Access the Player View by tapping a cell on the Recordings’ table view
- Delete a cell from Recordings’ table view
- Return to the Recorder view, by tapping the navigation bar’s Recorder button
By the way, when the app user delete a cell from the table view, the app will also delete the cell’s sound file from the application sandbox’s Documents directory.
Accessing The Sandbox’s Documents Directory
You already know that recorded sounds are saved in the application sandbox’s Documents directory. Before you get started in implementing above mentioned features in the AudioDiary project, let me walk you through the steps of accessing the application sandbox’s Documents folder so you can see recorded sounds files and and play them.
Before you begin, steps listed below assume you ran the AudioDiary project on the Simulator and you used the Recorder view to record one or more sounds. I also assume you used the Source Control menu to create a new branch called branch-two from the “branch-one” branch.
Now, to see the full path of the Documents directory, do the following:
1. Enter this statement in the RecorderViewController.swift file’s viewDidLoad() function.
/*** DEBUG STATEMENT ***/ let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) print(paths.first!)
2. Run the app in the sim.
The second statement print the full path to the sandbox’s Documents directory in Xcode’s Debugger console.
3. Copy the the Documents directory path.
4. Select the Go to Folder item from Finder’s Go menu. When you see the Go Folder box. Paste the directory path you copied in step 3.
5. Click the Go button and Finder take you to the AudioDiary application sandbox’s Documents directory. The sound file(s) you recorded appears in the Documents directory like this:
You can play the sound file via the QuickTime Player. Isn’t that cool!
The Recordings View Controller Code
You are ready to add code in the RecordingsViewController.swift class file. Start by entering code shown below in the fetchSoundsFiles() function.
I refer to the Simulator and your real device as “your device”. If you have a “real device”, you should use it to test code presented in this post. If not, then use the Simulator.
func fetchSoundFiles() { // Get the full path to the Documents directory let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) let docsDir = paths.first! do { // Get all files that are in the Documents folder let directoryItems: Array = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(docsDir) for item in directoryItems as [String] { if item.hasSuffix("txt") { //add only sound files in the tableView's dataSource array tableDataSource.append(item) } } } catch let error as NSError { print("Read Documents directory failed for this reason:\n\(error.localizedDescription)") } }
Test The RecordingsViewController Class Code
Now, run the app on your device. Code you entered in the fetchSoundFiles() populate the Recordings table view’s dataSource; which is an array variable called, tableDataSource. The Recordings view should look like this; assuming there’s only one sound file in the sandbox’s Documents directory.
Now, here is the code to add in the deleteAudioFile() function and the prepareForSegue() function.
func deleteAudioFile(soundFileToDelete: String) { let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) let documentsDirectoryPath = paths.first! let sourceFile = documentsDirectoryPath.stringByAppendingString("/"+soundFileToDelete) let fileManager = NSFileManager.defaultManager() do { try fileManager.removeItemAtPath(sourceFile) } catch let error as NSError { print("Failed to delete the sound file:\n\(error.localizedDescription)") } } // MARK: - Navigation override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { let controller = segue.destinationViewController as! PlayerViewController if segue.identifier == "showPlayer" { let indexPath = self.tableView.indexPathForSelectedRow controller.selectedAudioFileName = tableDataSource[indexPath!.row] } }
How The Recordings View Controller Code Works
It is time to explain how code in the RecordingsViewController.swift file work. Let us start with the viewDidLoad() function’s code.
The ViewDidLoad Function Code
Code in the ViewDidLoad() function set three properties of the tableView control and call the fetchSoundFiles() function. As you already know, that function fetch all sound files from the sandbox’s Documents directory and put only those that have the “caf” file extensions, in the table view’s dataSource array.
The Table View Data Source Code
Code in the table view’s data source functions pretty much populate the Recordings view’s table view cells. The table view data source functions are these:
- numberOfSectionsInTableView()
- numberOfRowsInSection()
- cellForRowAtIndexPath()
The Table View Cell Deletion Code
Code in the commitEditingStyle() function delete a swiped table view cell from the table view, and call the deleteAudiFile() function. That function take a single parameter, the soundFileToDelete. Code you entered in the function check to see if the soundFileToDelete exists in the sandbox’s Documents directory; if so, then remove it; otherwise print an error message in Xcode’s Debugger console.
The prepareForSegue() Function Code
Code in the prepareForeSegue() function perform these tasks:
- Put the PlayerViewController class in a variable called, controller.
- Pluck a sound file name from the tableDataSource array and pass to the PlayerViewController class.
That’s it, you’ve reached the end of part 2 of the tutorial. Use the Source Control menu to commit changes to the git repository. Next week, I will bring you the final part of the tutorial. In the mean time, comments are welcomed! 🙂