当应用程序在后台使用Swift 3

时间:2016-11-17 03:21:04

标签: ios swift swift3 avaudioplayer ios10

我正在制作一个运动应用程序,该应用程序需要能够在应用程序进入后台时以及屏幕锁定时播放声音。我还需要允许来自其他应用程序的声音(例如音乐),同时还允许我的声音效果通过。

我使用AVAudioSessionCategoryAmbient在iOS 9中工作,但只要我的应用程序变为非活动状态或屏幕锁定,声音就会停止。

这是我在演示应用中的代码的简化版本:

import UIKit
import AVFoundation

class ViewController: UIViewController {

var session: AVAudioSession = AVAudioSession.sharedInstance()
var timer = Timer()
let countdownSoundFile = "154953__keykrusher__microwave-beep"
let countdownSoundExt = "wav"
var audioPlayer = AVAudioPlayer()

override func viewDidLoad() {
    super.viewDidLoad()

    activateAudio()

}

func activateAudio() {
        _ = try? session.setCategory(AVAudioSessionCategoryAmbient, with: [])
        _ = try? session.setActive(true, with: [])
}

@IBAction func play() {
    timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(ViewController.playSound), userInfo: nil, repeats: true)
}

func playSound() {

    if let soundURL = Bundle.main.url(forResource: countdownSoundFile, withExtension: countdownSoundExt) {
        do {

            print("sound playing")
            try audioPlayer = AVAudioPlayer(contentsOf: soundURL)
            audioPlayer.prepareToPlay()
            audioPlayer.play()
        } catch {
            print("no sound found")
        }
    }

}
}

我还在背景模式中检查了Audio, Airplay, and Picture in Picture功能,后者为我的plist添加了必需的背景模式。

我正在设备上对此进行测试,一旦我锁定屏幕或按下主页按钮,我的声音就会停止,一旦我的应用再次激活,它们就会恢复。

我使用以下方法找到了解决方法:

var mySound: SystemSoundID = 0
AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
AudioServicesPlaySystemSound(mySound);

但是这不允许改变声音的音量,我还需要使用AVSpeechSynthesizer,这种解决方法并不适用。

关于如何使其发挥作用的任何想法?

编辑:

我将类别行更改为_ = try? session.setCategory(AVAudioSessionCategoryPlayback, with: [.mixWithOthers]),这样可以在应用运行时播放音乐,但是当屏幕锁定或进入后台时声音仍会停止。我需要声音在这些场景中继续播放。

编辑:

正如答案所指出的那样,当我的应用程序背景化时,我无法播放声音,但使用_ = try? session.setCategory(AVAudioSessionCategoryPlayback, with: [.mixWithOthers])可以在屏幕关闭时播放声音并与其他应用程序的声音(音乐)混合。

2 个答案:

答案 0 :(得分:4)

您无法在环境音频会话类别的后台播放。您的类别必须是播放。

要允许其他应用播放声音,请使用“混合”选项(.mixWithOthers)修改“播放”类别。

(另请注意,您可以随时更改您的类别。您可以在大多数情况下将其设置为环境,但在您知道自己即将进入后台时切换到播放,以便您可以继续玩。)

编辑此外,我发现还有另一种可能需要清理的错误概念。你不能(轻松地)在后台开始新的声音。当您的应用进入后台时,所有背景音频允许您继续播放当前声音。一旦声音停止(在后台),你的应用程序就会暂停,那就结束了。

答案 1 :(得分:2)

详细查看此处this answer。您还需要从应用程序设置启用音频模式。

do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: .mixWithOthers)
print("AVAudioSession Category Playback OK")
do {
    try AVAudioSession.sharedInstance().setActive(true)
    print("AVAudioSession is Active")
} catch {
    print(error)
}
} catch {
print(error)
}