在iOS上开始在后台播放声音?

Tom*_*ton 5 iphone audio avfoundation avaudioplayer ios

我正在尝试做类似Tile.app的事情。显示通知时,它会播放声音。这似乎很简单-使用UILocalNotification并包含声音文件名。但是本地通知将声音限制为不超过30秒,而Tile的声音会持续播放更长的时间。我希望它正在循环,并且一直持续到我再也受不了噪音为止。

即使手机的静音开关打开,声音也会播放,这在本地通知中不会发生。由于这些原因,UILocalNotification似乎已经淘汰了。

我以为也许我可以发布仅文本的本地通知,然后让我的应用播放声音。但是使用时AVAudioPlayer,该play方法会返回NO并且声音不会播放。

其他问题表明这是设计使然,应用程序不应该能够播放来自背景的声音-只能继续播放已经播放的声音。我会接受该推理,但Tile会这样做,因此这显然是可能的。建议的一种解决方法违反了Apple的准则,我可以肯定的是,Apple现在可以进行检查。

一些可能相关的细节:

  • audio在Info.plist中有后台模式
  • AVAudioSessionCategoryPlayback在音频会话上使用,并且该会话应该处于活动状态(至少setActive:error:声称成功)。
  • 这个应用程式使用蓝牙,但目前不使用bluetooth-central背景模式。

sag*_*444 3

实际上你可以使用其中一个AudioServices...函数

  • AudioServicesPlaySystemSound
  • AudioServicesPlayAlertSound
  • AudioServicesPlaySystemSoundWithCompletion

开始在后台播放声音。

我不确定可以提交的声音长度,AudioServicesCreateSystemSoundID因为我仅检查短循环声音是否响铃,但此 API 与通知无关,因此可能会超过 30 秒的限制。

编辑: 应用程序仍然需要audioUIBackgroundModes后台播放

从我的测试项目 appDelegate 中剪切,iOS 9.3.1

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // test sound in foreground.
    registerAndPlaySound()

    return true
}

func applicationDidEnterBackground(application: UIApplication) {
    var task =  UIBackgroundTaskInvalid
    task = application.beginBackgroundTaskWithName("time for music") {
        application.endBackgroundTask(task)
    }
    // dispatch not required, it's just to simulate "deeper" background  
    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(5 * Double(NSEC_PER_SEC)))

    dispatch_after(delayTime, dispatch_get_main_queue()) {
        self.registerAndPlaySound()
    }
}

func registerAndPlaySound() {
    var soundId: SystemSoundID = 0

    let bundle = NSBundle.mainBundle()
    guard let soundUrl = bundle.URLForResource("InboundCallRing", withExtension: "wav") else {
        return
    }
    AudioServicesCreateSystemSoundID(soundUrl, &soundId)

    AudioServicesPlayAlertSound(soundId)
}
Run Code Online (Sandbox Code Playgroud)

更新

在那里,我曾经beginBackgroundTask仅以最简单的方式启动声音,作为在另一个项目中在后台执行代码的最简单方法,类似于registerAndPlaySound从没有后台任务的回调中调用的代码PushKit