¿Comienza a reproducir el sonido en segundo plano en iOS?

Estoy tratando de hacer algo similar a Tile.app . Cuando muestra una notificación, reproduce un sonido. Eso parece bastante simple: use UILocalNotification e incluya el nombre del file de sonido. Pero las notifications locales limitan los sonidos a no más de 30 segundos, y el sonido de Tile sigue reproduciéndose durante mucho más time que eso. Espero que esté dando vueltas, y continúa hasta que ya no pueda soportar el ruido.

El sonido también se reproduce incluso si el interruptor de silencio del teléfono está encendido, lo que no sucede con las notifications locales. Por estos motivos, UILocalNotification parece estar fuera.

Pensé que tal vez podría publicar una notificación local solo de text y hacer que mi aplicación reproduzca el sonido. Pero al usar AVAudioPlayer , el método de play devuelve NO y el sonido no se reproduce.

Otras preguntas han sugerido que esto es por layout, que las aplicaciones no deben ser capaces de reproducir sonidos desde el background, solo continúan el sonido que ya está sonando. Aceptaré ese razonamiento excepto que Tile lo hace, por lo que es posible. Una solución sugerida viola las directrices de Apple de una manera que estoy bastante seguro de que Apple verifica por ahora.

Algunos detalles que pueden ser relevantes:

  • Tengo el modo de background de audio en Info.plist
  • Utilizo AVAudioSessionCategoryPlayback en la session de audio, y la session debe estar activa (al less, setActive:error: afirma tener éxito).
  • Esta aplicación usa Bluetooth, pero actualmente no usa el modo de background bluetooth-central .

En realidad, puedes usar una de las AudioServices... de AudioServices...

  • AudioServicesPlaySystemSound
  • AudioServicesPlayAlertSound
  • AudioServicesPlaySystemSoundWithCompletion

para comenzar a reproducir el sonido en segundo plano.

No estoy seguro acerca de la longitud de sonido que se puede enviar a AudioServicesCreateSystemSoundID porque estoy marcado solo con sonido de bucle corto para el timbre, pero esta API no vinculada a la notificación tan posible puede superar el límite de 30 segundos.

EDITAR: la aplicación aún requiere audio en UIBackgroundModes para jugar en segundo plano

Cut from my test project 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 requinetworking, 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) } 

Actualizar

Allí usé beginBackgroundTask para iniciar el sonido solo como la forma más simple de ejecutar código en segundo plano en otro proyecto similar al código para registerAndPlaySound se llamó a PushKit desde la PushKit llamada PushKit sin tarea de background.

De la documentation oficial de Apple :

"Los sonidos personalizados deben ser inferiores a 30 segundos cuando se reproducen. Si un sonido personalizado supera ese límite, el sonido del sistema pnetworkingeterminado se reproducirá en su lugar".

No hay forma de que UILocalNotication pueda hacer UILocalNotication bucle del sonido. Puede progtwigrlo de nuevo con intervalos de time de 30 segundos, pero esa será una progtwigción de otra alarma.

Para configurar su sonido de notificación personalizado:

 notif.soundName = @"sound.caf"; 

Asegúrate de que el sonido esté realmente en el package de tu aplicación, esté en el formatting correcto (PCM lineal o IMA4, en casi cualquier lugar que explica cómo convertir sonidos para iOS, y te indicará cómo hacerlo), y es inferior a 30 segundos.