使用 Swift 转换代码并出现多个错误(见图)

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

对编码非常陌生,到目前为止只学习 Swift,在制作未更新到 IOS 9 的 IOS 应用程序的课程中,在尝试转换时遇到这些错误.我已经解决了 2,但这些超出了我的范围,我无法继续前进。请帮忙。

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

您需要将无符号整数值 kAudioFormatMPEG4AAC 包装在 NSNumber 中,以将其放入该字典中。 AnyObject 表示该值必须是一个对象。如果是Any,那么它可以直接持有UInt32值。所以改用这个:

recordSettings[AVFormatIDKey] = NSNumber(unsignedInt: kAudioFormatMPEG4AAC)

而您的 URL 来自 NSURL.fileURLWithPathComponents(pathComponents) 是可选的,这意味着它可能为零。 API 需要一个永不为零的值,即一个不是可选的值。

如果您确定它会存在,您可以使用以下隐式解包:

self.audioRecorder = try AVAudioRecorder(URL: audioNSURL!, settings: recordSettings)

或者你可以做这样的事情来更安全:

if let audioNSURL = audioNSURL {
    self.audioRecorder = try AVAudioRecorder(URL: audioNSURL, settings: recordSettings)
}

下面是一些可以实际编译的代码:

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)
    }
}

请注意,我用 let 替换了几乎所有的 var。 默认情况下,您应该将所有变量设为 let,并且仅在以后需要更改值时才使用 var

还有一些其他风格上的变化不一定比您编写的代码更好,而是另一种编写方式 swift(例如使用字典文字语法而不是显式构造函数并使用 try?语法)。