Preface: I'm building an alarm clock app. Many other alarm apps such as Alarm Clock Pro are able to play an alarm while the screen is locked and the app is in the foreground. Their alarms can play for an unlimited amount of time and can progressively increase in volume using the system volume. They also do not take control of the music controls (if you open up the multitasking screen and scroll to playing audio, you will not see their icon)
I am having some trouble reproducing that functionality.
To play alarms while the app is in the foreground we fire Local notifications which works great. I've have some limited success while the screen is locked (the and the app is in the Inactive state)
I've used the following methods:
Run an
NSTimer
every second with a background task when the screen is locked. I managed to keep the app open past the 10 minute maximum but I was unable to play a sound. when the time camePlay a 1 second silent sound using
AVAudioPlayer
. When the sound ends, replay the sound and check if the app is in the Inactive (locked screen) state. If it is in the locked screen state and it's time to play an alarm, play it. The problem here is I must use[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
in order to continue updating the song while it's in the background. That method will display Wake in the music controls and will stop any currently playing music which we want to avoid.
- A combination of #1 and #2. When the app opens play a silent sound on infinite repeat. When the screen is locked fire a timer to check if its time to play an alarm. When it's time to play an alarm, switch the silent sound to the alarm sound. The system would eventually force close the app
Related knowledge that has helped but hasn't solved my question:
- How do I start playing audio when in silent mode & locked in iOS 6?
- iOS 5 deep sleep prevention
- Resuming execution of code after interruption while app is in background
- How to play music in background iphone sdk
Summary: While the screen is locked and in the app is in the foreground, I am unable to prevent the process from being killed off after the 10 minute mark.
UPDATE
I ended up using https://github.com/mruegenberg/MMPDeepSleepPreventer which let me play a sound after 10 minutes. However, this eats up battery like crazy. I need to find a more efficient solution.
UPDATE 2
I downloaded some of http://marcopeluso.com/ apps from the app store. He is the creator of the Deep Sleep Preventer. I downloaded some of his apps and ran some instruments tests and saw his app was not draining battery as much as my app is (roughly 2.5% per hour as claimed somewhere on his blog). I am very certain that I need to optimize my app and the battery drain problems will disappear and my problems will be solved!
UPDATE 3 I ended up using https://github.com/mruegenberg/MMPDeepSleepPreventer
I ran it in it's own separate xCode project and it only uses 0.5% of the cpu when the app is in the background. It turns out it was my app was sucking the cpu. So all it working well now :)