domingo, 25 de octubre de 2015

How to pass data from a viewController to another one

1. In the viewController RecordSoundsViewController we record an audio. This audio is represented by the class RecordedAudio. So in RecordSoundsViewController we have a variable recordedAudio of type RecordedAudio, that we want to pass to another viewController called PlaySoundsViewController that will play the audio.

1.1. class RecordedAudio

class RecordedAudio: NSObject{
    var filePathURL: NSURL!
    var title:String!

}

1.2. class RecordSoundsViewController

class RecordSoundsViewController: UIViewController, AVAudioRecorderDelegate {
    var recordedAudio:RecordedAudio!
}

1.3 class PlaySoundsViewController

class PlaySoundsViewController: UIViewController {
    var receivedAudio:RecordedAudio!
}

2. We will pass the data from RecordSoundsViewController to PlaySoundsViewController overriding the function prepareForSegue from UIViewController. The function prepareForSegue is called just before a segue is about to be performed. Inside the function we will controller that the segue is the one that we want because the scene could have multiple segues. The constant playSoundVC will be the destination view controller of the segue. The keyword "as!" convert the destinationViewController to the desired type PlaySoundsViewController. We get the data from the sender of the segue. We will pass the data to the recordedAudio in PlaySoundsViewController.


class RecordSoundsViewController: UIViewController, AVAudioRecorderDelegate {

    var recordedAudio:RecordedAudio!
        
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if(segue.identifier == "stopRecording") {
            let playSoundVC:PlaySoundsViewController = segue.destinationViewController as! PlaySoundsViewController
            let data = sender as! RecordedAudio
            playSoundVC.receivedAudio = data
        }
    }
}

How to implement a delegate

1. We have the class RecordSoundsViewController of type UIViewController. We want that this class implements a function included inside the class AVAudioRecorderDelegate called audioRecorderDidFinishRecording. The initial class is


class RecordSoundsViewController: UIViewController {
   var audioRecorder:AVAudioRecorder!

   @IBAction func recordAudio(sender: UIButton) {
        ...
        try! audioRecorder = AVAudioRecorder(URL: filePath!, settings: [:])
        ...
    }
}

2. We add the type AVAudioRecorderDelegate to this class


class RecordSoundsViewController: UIViewController, AVAudioRecorderDelegate {
   var audioRecorder:AVAudioRecorder!

   @IBAction func recordAudio(sender: UIButton) {
        ...
        tryaudioRecorder = AVAudioRecorder(URL: filePath!, settings: [:])
        ...
    }
}

3. After initialize the audioRecorder instance we declare that the class RecordSoundsViewController will be the delegate for audioRecorder

class RecordSoundsViewController: UIViewControllerAVAudioRecorderDelegate {
   var audioRecorder:AVAudioRecorder!

   @IBAction func recordAudio(sender: UIButton) {
        ...
        tryaudioRecorder = AVAudioRecorder(URL: filePath!, settings: [:])
        audioRecorder.delegate = self
        ...
    }
}

4. We add a function audioRecorderDidFinishRecording in the class RecordSoundsViewController

class RecordSoundsViewController: UIViewControllerAVAudioRecorderDelegate {
   var audioRecorder:AVAudioRecorder!

   @IBAction func recordAudio(sender: UIButton) {
        ...
        tryaudioRecorder = AVAudioRecorder(URL: filePath!, settings: [:])
        audioRecorder.delegate = self
        ...
    }

    func audioRecorderDidFinishRecording(recorder: AVAudioRecorder, successfully flag: Bool) {
        <#code#>
    }
}

Concepts:
- Class AVAudioRecorder has a variable called delegate of type AVAudioRecorderDelegate
class AVAudioRecorder{
   var delegate: AVAudioRecorderDelegate!
}

AVAudioRecorderDelegate is a list of methods, one of them audioRecorderDidFinishRecording
protocol AVAudioRecorderDelegate {
   func audioRecorderDidFinishRecording()
}

- In the RecordSoundsViewController of type AVAudioRecorderDelegate, when we see 
audioRecorder.delegate = self
we say that RecordSoundsViewController is becoming AVAudioRecorder.delegate so RecordSoundsViewController can implement the functions inside AVAudioRecorderDelegate like audioRecorderDidFinishRecording


miércoles, 21 de octubre de 2015

How to delete a segue between two views

- Select Main.storyboard in the Project Navigator

- Select the segue between the two scenes


- Click "delete" button in the keyboard

How to record audio


  1. Import library AVFoundation

  2. import AVFoundation

  3. Declare global variable with type AVAudioRecorder

  4. var audioRecorder:AVAudioRecorder!

  5. In the funtion to record the audio
    • Declare the directory where the files will be recorded

         let dirPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
    • Declare the filename

         let recordingName = "my_audio.wav"
    • Declare the filePath

         let pathArray = [dirPath, recordingName]
         let filePath = NSURL.fileURLWithPathComponents(pathArray)
    • Set the settings

         let session = AVAudioSession.sharedInstance()
         try! session.setCategory(AVAudioSessionCategoryPlayAndRecord)
    
    
    • Record the audio

         try! audioRecorder = AVAudioRecorder(URL: filePath!, settings: [:])
         audioRecorder.meteringEnabled = true
         audioRecorder.prepareToRecord()
         audioRecorder.record()
4. In the function to stop the record
         audioRecorder.stop()
         let audioSession = AVAudioSession.sharedInstance()
         try! audioSession.setActive(false)
    

How to change the name of a viewController file

The file will be named to RecordSoundsViewController.swift

Four things to do:
  • Change the name of the file in the Project Navigator.


  • Changes in the code inside the file
    • In the comments at the beginning of the file
    • The name of the class
     

  • The name of the class in the Identity Inspector.
    • Select in the Project Navigator the Main.storyboard
    • Select the scene associated to this ViewController, and in the Identity Inspector select the class.