【问题标题】:Swift Soundboard App斯威夫特音板应用程序
【发布时间】:2015-06-09 21:27:32
【问题描述】:

您好,我是一名使用 swift 的初学者程序员,正在尝试创建一个基本的音板模板。我的代码一直在 AppDelegate 中收到信号 SiGABRT,我不知道为什么。有人可以告诉我我的代码有什么问题,或者提供我可以用来创建音板的代码。到目前为止,这是我的 ViewController 所拥有的,任何帮助将不胜感激:

Class SoundListViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!
    var audioPlayer = AVAudioPlayer()
    var soundsArray: [Sound] = []
    var session = AVAudioSession.sharedInstance()
    var audioNSURL = NSURL()

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.dataSource = self
    self.tableView.delegate = self

    let samplePath = NSBundle.mainBundle().pathForResource("RandomSound", ofType: "m4a")
    audioNSURL = NSURL.fileURLWithPath(samplePath!)!
    audioPlayer = AVAudioPlayer(contentsOfURL: audioNSURL, error: nil)
    audioPlayer.prepareToPlay()

    var soundPath = NSBundle.mainBundle().pathForResource("RandomSound1", ofType: "m4a")
    var soundURL = NSURL.fileURLWithPath(soundPath!)
    var sounds1 = Sound()
    sounds1.name = "Sound1"
    sounds1.URL = soundURL!
    self.soundsArray.append(sounds1)

    soundPath = NSBundle.mainBundle().pathForResource("RandomSound2", ofType: "m4a")
    soundURL = NSURL.fileURLWithPath(soundPath!)
    var sounds2 = Sound()
    sounds2.name = "Sound2"
    sounds2.URL = soundURL!
    self.soundsArray.append(sounds2)

    soundPath = NSBundle.mainBundle().pathForResource("RandomSound3", ofType: "m4a")
    soundURL = NSURL.fileURLWithPath(soundPath!)
    var sounds3 = Sound()
    sounds3.name = "Sound3"
    sounds3.URL = soundURL!
    self.soundsArray.append(sounds3)

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.soundsArray.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = UITableViewCell()
    cell.textLabel?.text = self.soundsArray[indexPath.row].name
    println(cell)
    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var sound = self.soundsArray[indexPath.row]
    var baseString : String = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as! String
    var pathComponents = [baseString, sound.URL]

    var rowSoundURL = NSURL.fileURLWithPathComponents(pathComponents)!


    if audioPlayer.playing && rowSoundURL == audioNSURL {

        audioPlayer.stop()

    } else {

        audioNSURL = rowSoundURL

        self.audioPlayer = AVAudioPlayer(contentsOfURL: audioNSURL, error: nil)
        self.audioPlayer.play()

    }

    tableView.deselectRowAtIndexPath(indexPath, animated: true)

}

【问题讨论】:

    标签: swift tableview viewcontroller appdelegate


    【解决方案1】:

    这是您的代码中的一个简单错误;-) 在 vi​​ewDidLoad() 方法中,您只需将 soundURL 变量设置为媒体文件的完整路径(在这种情况下为 RandomSound1.m4a 等)

    在表视图委托的 didSelectRowAtIndexPath() 方法中,您可以执行以下操作:

    var sound = self.soundsArray[indexPath.row]
    var baseString : String = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as! String
    var pathComponents = [baseString, sound.URL]
    

    然后

    var rowSoundURL = NSURL.fileURLWithPathComponents(pathComponents)!
    

    这就是应用程序崩溃的部分。发生这种情况是因为 NSURL 类试图根据 baseString 和 sound.URL 创建一个 URL(如 RFC 1808、1738 和 2732 中定义的)。如果您将这些检查到变量中,它将如下所示:

    sound.URL => "file:///private/var/mobile/Containers/Bundle/Application/2D30CB30-919A-4253-AEFD-7386ED63A553/soundboard.app/take_5.m4a"
    
    baseString => "/var/mobile/Containers/Data/Application/63ADE8EB-DAE0-49E0-83A7-88378F675F9D/Documents" 
    

    所以当您现在组合这两个变量时,路径格式错误并导致崩溃。相反,您可以只使用 sound.URL,它会做您想做的事。

    我是这样实现的:

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            var sound = self.soundsArray[indexPath.row]
            var baseString = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as! String
    
            if let rowSoundURL = sound.URL {
                if audioPlayer.playing && rowSoundURL == audioNSURL {
    
                    audioPlayer.stop()
    
                } else {
    
                    audioNSURL = rowSoundURL
    
                    self.audioPlayer = AVAudioPlayer(contentsOfURL: audioNSURL, error: nil)
                    self.audioPlayer.play()
    
                }
            }
            tableView.deselectRowAtIndexPath(indexPath, animated: true)
        }
    

    注意:在我的例子中,Sound 的 URL 变量是可选的。让我知道它是否有效

    【讨论】:

    • 感谢您的帮助,我是编码新手,真的很想开发一个应用程序。当我实现您的代码时,出现“条件绑定中的绑定值必须是最佳类型”的错误。当我取出第一个 if 语句使其只有: let rowSoundURL = sound.URL { 出现错误说“无法使用类型为 (0 ->_) 的参数列表调用 URL。”我不太确定从这里做什么。
    • 不客气!错误出现在哪一行?我使用 XCode 6.3.2,我认为它使用 Swift 1.2。实际上我的声音对象看起来像这样:'import Foundation class Sound: NSObject { var name: String?变量 URL:NSURL? }' 如果您仍然有问题,请向我展示您的 Sound 对象的外观,以便我更新代码
    • 我也有同样的 Sound.swift 对象。 Xcode 在 let rowSoundURL = Sound.URL { 行上给我一个错误,说 Sound.type 没有名为 URL 的成员,尽管我很确定它确实有。同样 if audioPlayer.playing && rowSoundURL == audioNSURL { 和 audioNSURL = rowSoundURL 提出了在其自己的初始值中使用的错误变量。我猜这是因为 rowSoundURL 工作不正常,但我不是 100% 确定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 2017-03-24
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 2016-02-08
    • 2017-11-13
    相关资源
    最近更新 更多