title: Voice Recorder: speaker playback by default
body: <p>I've created a voice recorder that plays back through the earpiece; however, I want to play back by speaker. I've added the following (Swift 4):</p>
  
  <pre><code>let audioSession = AVAudioSession.sharedInstance()
  
      do {
          try audioSession.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
      } catch let error as NSError {
          print("Audio Session error: \(error.localizedDescription)")
      }
  </code></pre>
  
  <p>When I initialize the app, I am able to playback previous recordings by speaker; however, as soon as I record a new voice memo, the playback goes back to earpiece. I've looked up solutions but they all refer to setCategory which throws an error in Swift 4.</p>
  
  <p>Does anyone know how to default recorded playbacks to speaker?</p>
  
  <p>Here is my view controller in full:</p>
  
  <pre><code>import UIKit
  import AVFoundation
  
  class ViewController2: UIViewController, AVAudioRecorderDelegate, UITableViewDelegate, UITableViewDataSource {
  
  
  // Setting up Table View
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
      return numberOfRecords
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
      cell.textLabel?.text = String(indexPath.row + 1)
      return cell
  }
  
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      let path = getDirectory().appendingPathComponent("\(indexPath.row + 1).m4a")
  
      do {
          audioPlayer = try AVAudioPlayer(contentsOf: path)
          audioPlayer.play()
      }
  
      catch {
  
      }
  }
  
  
  var audioPlayer : AVAudioPlayer!
  var recordingSession : AVAudioSession!
  var audioRecorder : AVAudioRecorder!
  
  var numberOfRecords : Int = 0
  
  @IBOutlet weak var buttonLabel: UIButton!
  @IBOutlet weak var myTableView: UITableView!
  
  @IBAction func record(_ sender: Any) {
      // Check if we have an active recorder
      if audioRecorder == nil {
          numberOfRecords += 1
          let filename = getDirectory().appendingPathComponent("\(numberOfRecords).m4a")
  
          let settings = [AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                          AVSampleRateKey: 12000,
                          AVNumberOfChannelsKey: 1,
                          AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue]
  
          // Start audio recording
          do {
              audioRecorder = try AVAudioRecorder(url: filename, settings: settings)
              audioRecorder.delegate = self
              audioRecorder.record()
  
              //buttonLabel.setTitle("Stop", for: .normal)
          }
  
          catch {
              displayAlert(title: "Oops!", message: "Recording failed")
          }
      }
      else {
          // Stop audio recording
          audioRecorder.stop()
          audioRecorder = nil
  
          UserDefaults.standard.set(numberOfRecords, forKey: "myNumber")
          myTableView.reloadData()
  
          //buttonLabel.setTitle("Start", for: .normal)
      }
  
  }
  
  override func viewDidLoad() {
      super.viewDidLoad()
  
      // Setting up Recording session
      recordingSession = AVAudioSession.sharedInstance()
  
      if let number : Int = UserDefaults.standard.object(forKey: "myNumber") as? Int {
          numberOfRecords = number
      }
  
      AVAudioSession.sharedInstance().requestRecordPermission { (hasPermission) in
          if hasPermission {
              print ("Accepted")
          }
      }
  
      // Play speaker instead of earpiece
      let audioSession = AVAudioSession.sharedInstance()
  
      do {
          try audioSession.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
  
      } catch let error as NSError {
          print("Audio Session error: \(error.localizedDescription)")
      }
  
  
      // Gesture recognizers
  
      let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(swipe:)))
      leftSwipe.direction = UISwipeGestureRecognizer.Direction.left
      self.view.addGestureRecognizer(leftSwipe)
  
      let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(swipe:)))
      rightSwipe.direction = UISwipeGestureRecognizer.Direction.right
      self.view.addGestureRecognizer(rightSwipe)
  
      let upSwipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(swipe:)))
      upSwipe.direction = UISwipeGestureRecognizer.Direction.up
      self.view.addGestureRecognizer(upSwipe)
  
  }
  
  override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
  }
  
  
  // Function that gets path to directory
  func getDirectory() -&gt; URL {
      let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
      let documentDirectory = paths[0]
      return documentDirectory
  }
  
  // Function that displays an alert
  func displayAlert(title: String, message: String) {
      let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
      alert.addAction(UIAlertAction(title: "dismiss", style: .default, handler: nil))
      present(alert, animated: true, completion: nil)
  }
  </code></pre>