如何在单例方法中实现AVAudioPlayer?

3

这是我的代码:

class SomeAudioManager: NSObject
{

    class var sharedInstance: SomeAudioManager{
        struct Static {
            static var onceToken: dispatch_once_t = 0
            static var instance: SomeAudioManager? = nil
        }
        dispatch_once(&Static.onceToken) {
            Static.instance = SomeAudioManager()
        }
        return Static.instance!
    }
    func audioView(songname: NSString,format: NSString)
    {
        let audioPlayer:ava
        audioPlayer=try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(songname, ofType:format)!), fileTypeHint: AVFileTypeMPEGLayer3)
        audioPlayer!.delegate=self;
        self.audioPlayer!.play()
    }
}

AVAudioPlayer属于NSObject,但我无法实现它。

当我输入let audioPlayer: AVAudio时,它没有显示任何内容。

2个回答

2

虽然这没有太多意义,但是对我来说可以编译:

import AVFoundation
class SomeAudioManager: NSObject, AVAudioPlayerDelegate
{
    class var sharedInstance: SomeAudioManager {
        struct Static {
            static var onceToken: dispatch_once_t = 0
            static var instance: SomeAudioManager? = nil
        }
        dispatch_once(&Static.onceToken) {
            Static.instance = SomeAudioManager()
        }
        return Static.instance!
    }
    func audioView(songname: String,format: String) {
        let audioPlayer: AVAudioPlayer

        do {
            audioPlayer = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(songname, ofType:format)!), fileTypeHint: AVFileTypeMPEGLayer3)
            audioPlayer.delegate = self;
            audioPlayer.play()
        } catch {
            // error
        }
    }
}

所以你需要导入框架,在Swift中,try-catch语法是do-try-catch。一些其他的语法错误也被修复了。

顺便说一下,在Swift中单例不是这样使用的。

用法:

class someOtherClass {
    func doSomething() {
        SomeAudioManager().audioView("name_here", format: "format_here")
        SomeAudioManager.sharedInstance.audioView("name_here", format: "format_here")
    }
}

编辑后添加用法示例。第一行使用新实例,第二行使用共享实例。 - Matic Oblak
2015-12-23 19:07:48.980 Ss[2549:153426] 19:07:48.980 警告:40:错误:无法获取默认输入设备,ID = 0,err = 0! 2015-12-23 19:07:48.981 S[2549:153426] 19:07:48.981 警告:40:错误:无法获取默认输出设备,ID = 0,err = 0! 2015-12-23 19:07:48.981 S[2549:153426] 19:07:48.981 错误:708:找不到有效的输入或输出设备! 2015-12-23 19:07:48.982 S[2549:153426] 19:07:48.982 错误:312:错误-66680 - Kishore Kumar
你这里的单例模式没有意义。如果你可以解释一下你想要实现什么,我可以给你建议。 - Matic Oblak
我正在尝试在两个视图控制器中播放音频,所以我想如果将其作为单例方法,就可以避免歌曲合并。 - Kishore Kumar
那么在不合并的情况下应该发生什么?重新开始播放还是简单地中断操作?如果第一个已经播放完了会发生什么? - Matic Oblak
显示剩余4条评论

2

就评论中提到的单例部分而言,您可能应该使用类似于以下内容的代码:

class MyAudioPlayer: NSObject, AVAudioPlayerDelegate {
    private static let sharedPlayer: MyAudioPlayer = {
        return MyAudioPlayer()
    }()

    private var container = [String : AVAudioPlayer]()

    static func playFile(name: String, type: String) {
        var player: AVAudioPlayer?
        let key = name+type
        for (file, thePlayer) in sharedPlayer.container {
            if file == key {
                player = thePlayer
                break
            }
        }
        if player == nil, let resource = NSBundle.mainBundle().pathForResource(name, ofType:type) {
            do {
                player = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: resource), fileTypeHint: AVFileTypeMPEGLayer3)
            } catch {
                // error
            }
        }
        if let thePlayer = player {
            if thePlayer.playing {
                // already playing
            } else {
                thePlayer.delegate = sharedPlayer
                sharedPlayer.container[key] = thePlayer
                thePlayer.play()
            }
        }
    }
}

使用方法如下:

MyAudioPlayer.playFile("Breach", type: "mp3")

非常感谢 @Matic Oblak,提前祝您圣诞节快乐 :) - Kishore Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接