M.J. M.J. - 3 months ago 20
iOS Question

Converted code using Swift and got multiple errors (see image)

Very new to coding and only learning Swift so far, in a course to make IOS apps that is not updated to IOS 9 and when trying to convert got these errors. I've resolved 2 but these are beyond my scope and I can't move forward. Please help.

import UIKit
import AVFoundation
class NewSoundViewController: UIViewController {

required init?(coder aDecoder: NSCoder) {
var baseString : String = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]

var pathComponents = [baseString, "MyAudio.m4a"]
var audioNSURL = NSURL.fileURLWithPathComponents(pathComponents)
var session = AVAudioSession.sharedInstance()
do {
try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
} catch _ {
}

var recordSettings: [NSObject : AnyObject] = Dictionary()
recordSettings[AVFormatIDKey] = kAudioFormatMPEG4AAC
recordSettings[AVSampleRateKey] = 44100.0
recordSettings[AVNumberOfChannelsKey] = 2

self.audioRecorder = try AVAudioRecorder(URL: (audioNSURL)!, settings: recordSettings)
self.audioRecorder.meteringEnabled = true
self.audioRecorder.prepareToRecord()
}


Error message in code

Answer

Here is some code that will actually compile:

class NewSoundViewController: UIViewController {

    private var audioRecorder : AVAudioRecorder?

    required init?(coder aDecoder: NSCoder) {

        let session = AVAudioSession.sharedInstance()

        do {
            try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
        } catch _ {
            // TODO: actually handle the error.
        }

        let baseString = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]
        let pathComponents = [baseString, "MyAudio.m4a"]
        if let audioNSURL = NSURL.fileURLWithPathComponents(pathComponents) {

            var recordSettings = [String : AnyObject]()
            recordSettings[AVFormatIDKey]         = Int(kAudioFormatMPEG4AAC)
            recordSettings[AVSampleRateKey]       = 44100.0
            recordSettings[AVNumberOfChannelsKey] = 2

            // TODO: error handling
            let audioRecorder = try? AVAudioRecorder(URL: audioNSURL, settings: recordSettings)
            self.audioRecorder = audioRecorder
            self.audioRecorder?.meteringEnabled = true
            self.audioRecorder?.prepareToRecord()
        }

        // need to call super.init
        super.init(coder: aDecoder)
    }
}

Note that I replaced almost all of the vars with lets. By default you should make all of your variables let, and only use var if you need to change the value later on.

There are some other stylistic changes that aren't necessarily better than the code you wrote, but an alternate way of writing swift (like using the dictionary literal syntax instead of the explicit constructor and using try? syntax).