I want to create a feature in my app the makes a sound every 5 seconds. The sound file is short and in order to play it every 5 seconds i use a timer.
The issue is i want to play it even if the app is in the background for a maximum time of 30 min and could also be different bpm for each user. I have used background audio mode to do it but i could find in the documentation how does playing sounds is threated by the system i dont want my app to be suspended. I only saw referance to playing music songs in the background with a player.
How can i be certain i will receive the background time needed just for playing small sounds every few seconds and not playing continues music? I was thinking about empty sound wave file but afraid apple would reject my app.
Thanks for any help i can get.
Related
I am making an alarm clock app. To play the alarm sound at the appropriate time, I use myAudioPlayer.play(atTime: myAudioPlayer.deviceCurrentTime + secondsUntilAlarm). This way, even if the app is in the background, the audio player plays the alarm sound at the appropriate time.
Note: I got this idea from a different SO answer, which unfortunately I can't seem to find right now.
However, what I've noticed is that alarms are being played correctly if the secondUntilAlarm value is relatively soon, like maybe 20 minutes or less (converted to seconds of course since that's what the method requires). However, if it's longer than that, the sound does not play. Is there something I'm missing with how this method works in the background? Could the app be entering some sort of suspended state or something that disables the audio player from triggering the playback?
Any suggestions or comments would be appreciated--thanks!
So I've actually determined that it does not matter if the app enters the suspended state (in fact, this is expected). I've identified that the reason the alarm sound does not play sometimes because I open another app with audio that deactivates my app's audio session (therefore, it has nothing to do with the time the alarm is set for). To fix this, all I had to do was ensure I set .mixWithOthers for my app's audio session. That way, other audio sessions from other apps don't deactivate mine!
I have a sports assistant application.
And I need to play sounds at certain points in time (not constantly).
For example, the application pronounces how many kilometers or minutes the user ran.
But as I know, the application must constantly play the sound (silence is prohibited) in the background, otherwise it will be closed.
Is there any way to play audio at indefinite intervals in the background?
Note: I watched other questions and everywhere suggest to play silence in the background.
Solution below
I am working on a running app which gives voiceover instruction at the start of each exercise. It works as intended when the device is active but doesn't work when the phone is locked. [Current audio continues but no future audio plays.]
Question
How can I start playing an audio voiceover while the users iPhone is locked.
Currently I track the workout using Timer.scheduledTimer for 2 timers I display [current activity and the overall workout]. When the timer hits a pre-defined time towards the end of one activity, the voiceover audio plays to introduce the next activity. The timer firing is what starts the audio and I believe this is the issue. I can pause the workout, skip sections and all works fine - until the device is locked.
If an audio voiceover is playing when I press the home button or lock the iPhone it continues to play as expected. The issue is then that the timer doesn't fire so the next audio voiceover [in say 90 seconds] is never played.
Some of the answers and comments I've read have said that this functionality just isn't possible in iOS. The Couch to 5k app https://itunes.apple.com/gb/app/one-you-couch-to-5k/id1082307672?mt=8 uses this functionality so I know it's possible to achieve, I just don't know how they're doing it. [It will be a dedicated member that downloads it to see what I mean :)]
From searching SO I've read a lot of post saying that Timer or NSTimer can't run when the app is in the background or the phone is locked. Any posts that say it can work are old and based on iOS4/5
I've read about suggestions of using silence and essentially having 1 long audio file. While this would pose some new challenges for skipping the sections in the workout I've also read comments that say this behaviour would not pass Apple's testing of the app for the AppStore. The 3rd downside being that my audio file size would increase.
An option I've seen is local notifications, however I'm yet to see an example of one used to play audio voiceover when the app is in the background.
How can I achieve the same functionality as the Couch to 5k app?
Thanks
Ok, I worked up a solution to play audio prompts to the user throughout the course of a 30 minute workout, even if the iPhone is locked or the app is in the background. The app has been submitted and approved for the AppStore.
To get the app to perform as required I use 2 AVAudioPlayers; one plays the voiceover, the other plays a 15 minute track of silence [as it’s a separate track and just silent it’s a low quality .mp3 and only added 900kb to the app size]. 15 minutes well exceeds any interval between voiceovers so it works perfect.
When the user starts an exercise the first audio prompt is played. From that point, until the user stops the exercise there will be audio playing in the background. Because background audio is playing, the Timer still operates.
When a voiceover finishes, the AVAudioPlayerDelegate method audioPlayerDidFinishPlaying is called. Within this method I reset the audio properties [I’ll explain why shortly], instantiate my silent AVAudioPlayer, and start playing the 15 minute track of silence. Playing another track using this delegate method means that there is no real break in background audio so the app is kept alive. With the app ‘alive’ the timer continues to countdown. When it’s time for another voiceover the timer calls a method which resets the audio category, instantiates my voiceover AVAudioPlayer and plays a voiceover. This process is repeated until the final voiceover. When that completes no further silence is played and the app can safely be backgrounded.
The audio voiceover needs to duck the users music [reduces the music volume so that the audio can be clearly heard]. The silent audio shouldn’t do that, music should continue to play at full volume. As both AVAudioPlayers use the AVAudioSession.sharedInstance I found that I had to deactivate the sharedInstance, reset the properties, with or without .duckOthers, and then reactivate the sharedInstance before instantiating my AVAudioSession. That then gave me the desired result. Constant background audio that only ducked the users music when a voiceover played.
do{
try AVAudioSession.sharedInstance().setActive(false)
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.interruptSpokenAudioAndMixWithOthers, .duckOthers])
try AVAudioSession.sharedInstance().setActive(true)
} catch{
print(error.localizedDescription)
}
I know that some said Apple do not allow silent audio, however, in this circumstance the silent audio only plays for the duration of the exercise routine. As soon as it ends the app can terminate, thereby not keeping the app alive any longer than necessary.
My understanding of VoiceOver leads me to the way that only a foreground application can control what it reads out.
You need focusing with VoiceOver to make it speak and you focus nothing when the device is locked or your app is in the background mode.
I suggest to take a look at the speech synthesis or the AVAudioSession class to enable background audio: both might be good workarounds to take over in the background mode: just try and let us know. ;o)
I have an app that under certain circumstances needs to play audio the moment it is pushed into background.
I can't use any background key, as I don't fulfill any requirements for these and Apple rejected my app, when I tried to use the background audio key.
Currently I'm start playing the audio file and then request extra processing time within applicationDidEnterBackground: The audio never gets played even though I have the processing time and the app is still running (I've used an NSTimer to check every 2 seconds).
As audio mode I'm using AVAudioSessionCategoryPlayback with AVAudioSessionCategoryOptionMixWithOthers.
With active background audio mode this works fine.
I also know, that I could use local notification and play the audio file there (as it is under 30 seconds), but that would be my last resort.
Does Apple prevent audio from being played in applicationDidEnterBackground: ?
I get a callback for audioPlayerBeginInterruption: immediately.
I've seen:
Why does the following code to play audio in the background not work?
But this doesn't seem to work anymore on iOS8.
Thanks :)
Your app should not be playing a sound (and certainly not a sound of any length) just because the user backgrounds it, and now Apple has succeeded in stopping you from doing this. You should accept this, abandon your attempts to work around this perfectly reasonable restriction, and move on.
I wondering if there was a way to play a sound or music for a predetermined duration even if the app is put into the background.
For instance, say the sound is 30 mins long but only want to play it for 10 mins, how can I pause the sound while in the background. Or is there a way to tell AVAudioPlayer to loop 0.333 times?
Is there a better class to use instead of AVAudioPlayer to achieve this?
EDIT:
So far I've searched SO and Google to no avail. And have been reading through Apple's docs.
Thanks in advance for the help.
Two solutions:-
-1. You can have Local and Push Notification
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008194-CH1-SW1
Notification can play sound when delivered.
-2. You can make you app run in background and play sound
http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
iOS/iTunes rules limit what you can do in background to pass moderation but it mentions playing music.