As I have promised three weeks ago (and again a few days ago) I finally got around to writing this little how-to.
I’m sorry for the delay. I hope this helps someone, anyway.
Mind you, this is my first attempt at writing a how-to, and most of it was done, while I was being tired. Also, English isn’t my native language, so please excuse any typos or other errors, you may find.
If you have any suggestions, how to improve this, please feel free to leave a comment.
Now, have fun!
Preface
We will create an iPhone application, that keeps the iPhone from deep sleeping, while it’s running. It’s not a really useful application, as it does nothing but just that, but you can easily adapt the stuff you learn here and use it for your own application(s).
Here’s exactly what we’re going to do:
We will …
- … create a new project in Xcode.
- … add the necessary frameworks to this project.
- … add a silent sound file to this project.
- … create a class called “DeepSleepPreventer” and add it to this project.
- … then use this class to prevent the iPhone from deep sleeping.
You can use this class in your other apps, to prevent them from sleeping. Just add the needed frameworks and the DeepSleepPreventer class to your app and use the DeepSleepPreventer, whenever you need it.
Create a New Project in Xcode
I’m sure you all know, how to do this, but for completeness’ sake, I’ll just go through the whole process, step by step.
Fire up Xcode. Click “File” -> “New Project”. We are gonna use the “View-based Application” template for this how-to, so select it and click “Choose…”.

Choose a location and name under which you want to save the project and click on “Save”. I’m going to use “iPhoneInsomnia” as a name and save the project to my desktop (I know, I have a lot to tidy, judging by the screenshot).

Add the Necessary Frameworks
Now we’ll add the AVFoundation and the AudioToolbox frameworks to our project, as we will need them later on.
In your project window, right-click (or control-click) your “Frameworks” group in the “Groups & Files” pane and click on “Add” -> “Existing Fameworks…”.

A file selection window should pop up now and it should show you the content of the current iPhone SDK’s “Library” subfolder. If your starting up somewhere else, navigate to “/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library” first (see screenshot).

Further go to the Frameworks folder and select “AudioToolbox.framework” and “AVFoundation.framework”. Then click on “Add”.

In the upcoming window uncheck the “Copy …” checkbox, if it is selected and choose “Relative to Current SDK” as reference type. Then click “Add”.

Add a Silent Sound File
Now we need to add a silent sound file. You can create it with a sound tool of your choice. I named it “noSound.wav”. You can just use the file I created, if you like. It is part of the Github repository I created for this whole project. iPhoneInsomnia @ Github
We will first create a new group, named “DeepSleepPreventer” in the “Groups & Files” pane. Because we are very tidy people, we will add the sound file and our later created custom class to this group, too.
Right-click on “iPhoneInsomnia” and click on “Add” -> “New Group” and name it “DeepSleepPreventer”.

Now right-click this group and click “Add” -> “Existing Files…” and add the sound file to the project.

Navigate to the location of your sound file, select it and click “Add”.

Check the “Copy items …” checkbox and set “Reference Type” to “Default”. Click Add.

Create our New Class
Now it’s time to finally write some code. Almost. First we need to add a new class to the project.
Right-click the “DeepSleepPreventer” group and click “Add” -> “New File…”.

Choose the “Objective-C class” template under “iPhone OS” -> “Cocoa Touch Class” and select “NSObject” on the “Subclass of” pull down. Click “Next”.

Name the file “DeepSleepPreventer.m”, Check the “Also create .h” checkbox and click “Finish”.

Now modify “DeepSleepPreventer.h” to look like this:
#import <Foundation/Foundation.h>
@class AVAudioPlayer;
@interface DeepSleepPreventer : NSObject {
AVAudioPlayer *audioPlayer;
NSTimer *preventSleepTimer;
}
@property (nonatomic, retain) AVAudioPlayer *audioPlayer;
@property (nonatomic, retain) NSTimer *preventSleepTimer;
- (void)playPreventSleepSound;
- (void)startPreventSleep;
- (void)stopPreventSleep;
@end
We declared two properties here: an AVAudioPlayer here, that will play our silent sound file and an NSTimer that will call -playPreventSleepSound. We actually create this timer in -startPreventSleep and invalidate it in -stopPreventSleep later.
Now we edit “DeepSleepPreventer.m” step by step.
First we import some header files, synthesize our accessors and mutators (or getters and setters, if you prefer to call them that):
#import "DeepSleepPreventer.h"
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
@implementation DeepSleepPreventer
@synthesize audioPlayer;
@synthesize preventSleepTimer;
Modify -init to set up all the stuff we need to:
- (id)init
{
if ((self = [super init])) {
// Activate audio session
AudioSessionSetActive(true);
// Set up audio session, to prevent iPhone from deep sleeping, while playing sounds
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (
kAudioSessionProperty_AudioCategory,
sizeof (sessionCategory),
&sessionCategory
);
// Set up sound file
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"noSound"
ofType:@"wav"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
// Set up audio player with sound file
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[self.audioPlayer prepareToPlay];
// You may want to set this to 0.0 even if your sound file is silent.
// I don't know exactly, if this affects battery life, but it can't hurt.
[self.audioPlayer setVolume:0.0];
}
return self;
}
Now we implement -playPreventSleepSound:
- (void)playPreventSleepSound {
[self.audioPlayer play];
}
This should be self explanatory.
Now -startPreventSleep (this is the method we will call, if we want the iPhone to stay awake):
- (void)startPreventSleep {
// We need to play a sound at least every 10 seconds to keep the iPhone awake.
// We create a new repeating timer, that begins firing now and then every ten seconds.
// Every time it fires, it calls -playPreventSleepSound
self.preventSleepTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0]
interval:10.0
target:self
selector:@selector(playPreventSleepSound)
userInfo:nil
repeats:YES];
// We add this timer to the current run loop
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:self.preventSleepTimer forMode:NSDefaultRunLoopMode];
}
-stopPreventSleep stops the sleep preventing.
- (void)stopPreventSleep {
[self.preventSleepTimer invalidate];
self.preventSleepTimer = nil;
}
Finally -dealloc to clean up our mess:
- (void)dealloc {
// memory management
[preventSleepTimer release];
[audioPlayer release];
[super dealloc];
}
// Don't forget the matching @end to our @implementation
@end
Use the DeepSleepPreventer Class
Now switch to “iPhoneInsomniaAppDelegate.h”. We will add a property if the type or our class DeepSleepPreventer to the application delegate now. Modify “iPhoneInsomniaAppDelegate.h”, to look like this:
#import <UIKit/UIKit.h>
@class iPhoneInsomniaViewController;
@class DeepSleepPreventer;
@interface iPhoneInsomniaAppDelegate : NSObject {
UIWindow *window;
iPhoneInsomniaViewController *viewController;
DeepSleepPreventer *deepSleepPreventer;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet iPhoneInsomniaViewController *viewController;
@property (nonatomic, retain) DeepSleepPreventer *deepSleepPreventer;
@end
Now move on to “iPhoneInsomniaAppDelegate.m”. We will instantiate and use our DeepSleepPreventer class in -applicationDidFinishLaunching:. In your own app, you would do this in a place, where it fits best.
First we need to import our class header file and synthesize our new property:
#import "iPhoneInsomniaAppDelegate.h"
#import "iPhoneInsomniaViewController.h"
#import "DeepSleepPreventer.h"
@implementation iPhoneInsomniaAppDelegate
@synthesize window;
@synthesize viewController;
@synthesize deepSleepPreventer;
Now modify -applicationDidFinishLaunching: to look like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Here we create our deepSleepPreventer and get it to keep our iPhone from deep sleeping
self.deepSleepPreventer = [[DeepSleepPreventer alloc] init];
[self.deepSleepPreventer startPreventSleep];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
And finally the rest of “iPhoneInsomniaAppDelegate.m”. Release our property in -dealloc:
- (void)dealloc {
[deepSleepPreventer release];
[viewController release];
[window release];
[super dealloc];
}
// Don't forget the matching @end to our @implementation
@end
Well, that’s it! We are done! :)
Use This in Your Own App
Just add the two frameworks “AVFoundation.framework” and “AudioToolbox.framework” to your own app, add the sound file “noSound.wav” and the files “DeepSleepPreventer.h” and “DeepSleepPreventer.m” to it and instantiate and use an object of the “DeepSleepPreventer” class where it fits best, and you’re ready to go.
Issues and Epilog
I couldn’t start my MPMusicPlayer in my music alarm clock app, while I was playing the silent sound with the AVAudioPlayer. So I’m guessing, it’s not possible to play other sounds while this sound plays, at least not via the MPMediaPlayer class.
As I didn’t use any other sounds in my applications yet, I don’t know if this assumption is correct. If you have any more experience with this or any more other useful or relevant information, please leave a comment. I will then update this how-to.
Also, as Shabbir Vijapura pointed out in a comment to my previous post there might be an easier way, to run timers on the iPhone, while it is asleep. I haven’t tested this myself, yet, though, so I cannot guarantee, that this really works. I will test it in the the next couple of days and then update this post, if I find the time.
Update: Appearantly this method, doesn’t work, as Shabbir pointed out in the comments.
Furthermore, if you have any experience yourself, dealing with the iPhone’s deep sleep behaviour and would like to share, or if you have any other suggestions or questions, please feel free to leave a comment.
Thanks for reading. I hope this is useful to someone out there.
Downloads
You can download this project, including all source code and the silent sound file. Feel free, to use it in your own apps.
I realized my way doesn’t work after about an hour on battery power alone. I had a question though, technically could you just play a silent sound ever 10 seconds right in your view controller. Then when the alarm is ready to go off, invalidate the NSTimer and call it again when the alarm is stopped? That’s what I tried, but it didn’t work when I used it on battery power alone and my alarm was set for 5 hours later.
Sorry to hear that, I’m just glad I didn’t test it myself, yet. Thanks for the heads up!
What you tried should work. In fact, that’s exactly what I did with TuneAlarm, while working this out.
Remember, it’s important to configure the audio session correctly. Look at DeepSleepPreventer’s -init method. It only works, when you set the “AudioSessionProperty_AudioCategory” to “kAudioSessionCategory_MediaPlayback”.
*edit: What just came to my mind: Maybe it’s possible to combine the you method with mine somehow, and save some more battery life. You should try that and tell me, if it works! :P
Hi I have tried using your example but I can’t seem to get it to work. I want to keep the iPhone awake so I can set off an alarm after a period of time. Your code works to play the sound (I have tried it with an audio so I can tell it’s working), but the iPhone still locks and my alarm sound doesn’t get played. What am I doing wrong??
You have to call [DeepSleepPreventer -stopPreventSleep] before you play another sound, as the audio session in this project isn’t set to allow mixing in other sounds.
I have updated the class already to allow mixing. I will push it to the GitHub repo now. I will probably not update the blogpost, though because of laziness.
Thanks so much! I’ve incorporated this into my GPS app and it works perfectly. I’d been searching for this information for a long time.
Glad I could help. :)
Marco,
A lifesaver to be sure! I stuck a label and another NSTimer in your app which counted off seconds. 15 minutes later I woke the app again on the iPhone and it showed 15 minutes had passed and had been accurately counted. A smile came on my face. Thanks again for all the hard work.
Have you tested it playing concurrently music from iPod (MPMusicPlayerController)? It seems that doesn’t work for this case…
Thanks!
The code in this blogpost doesn’t work for that. The code in iPhoneInsomnia @ GitHub has been updated to allow mixing in other sounds, though.
Thanks for sharing.
I may be interested as I am building an app to monitor my server at night.
Actually the app is still running even after screen went off.
Can you tell me how long my application can run before entering deep sleep ?
I mean without your code of course :-)
sorry you can delete my posts. I noticed that my app still run only if iphone plugged.
I will try you code.
Done.
Thanks Marco for the idea. I did not use your code actually but the idea is the same : Play a silent sound each 10s
Here is the code for those interested :
Need :
– a Silent.aiff sound in Resources
– a Timer that launch that code each 10s
– AudioToolbox framework
// Play a sound to avoid go standby
NSString *path = [NSString stringWithFormat:@"%@%@",
[[NSBundle mainBundle] resourcePath],
@”/Silent.aiff”];
SystemSoundID silentSoundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &silentSoundID);
AudioServicesPlaySystemSound(silentSoundID);
@Marco
Why do we need all such tweaks? Apple documentation doesnt claim that they switch off any services when the device falls into sleep mode.
It is the responsibility of programmer to switch off GPS / any services in -appWillResignActive and switch on again in -appDidBecomeActive.
If services are not turned off in -appWillResignActive, then iPhone device should ideally be receiving GPS updates, isnt it ???
I don’t know about that, as I haven’t been looking into the GPS stuff, yet.
For my alarm clock app, this was necessary to get it to work, though.
@Marco
Yesterday after commenting here, I took the device for a field test with our app.
In my code, while device goes into sleep mode (in -appWillResignActive) I am not turning off the GPS CLLocation updates if user is already running some GPS related features. But though I was surprised to see that the device indeed does not get any GPS updates if it goes into sleep mode.
This behavior is nowhere mentioned in the apple docs that they turn off the GPS updates automatically, or may be I have missed some critical points in docs, in which case somebody please correct me.
I have to try out your solution and then will report back, until then please keep updating with any information.
Thnx
Hi there. Thanks for your code. i Just downloaded the code from the repo you mentioned. I am trying to develop an alarm app which needs to fire even at iphone lock screen, so i used your classes and instantiated from it in my program using the same nSound.wav in my project.
Now the problem is its not working for me. Infact i m developing a JB iPhone and playing with a LaunchDaemon. That launchDaemon is going to use your classes.
Code is working great when the screen is locked but its not working when screen is locked. Any advice on this??
Hey.
I just used your classes by downloading them from the link you gave. I have two questions
1) you wrote in comments FIXME:change this to private
What does this mean?
2) I imported your classes and called in my app, i came to know that PlayPreventSleepSound method is not being called, dont know why.
Some suggestions would be appreciated !!!
Hi
I have tried your method and the classes you provided, they actually work, thanks for your work but the problem is that they eat up the battery like hell. Since our App is not the only one running all the time, there are some LaunchDaemons which are always working in the background so the battery performance is very bad using this idea.
It’s the only way I know how to run an App in the background. If you find a way to do this that eats less battery, please let me know.
Hi Marco,
I noticed that your code was not successfully allowing the audio session to mix with other sessions (i.e. the iPod), but I believe I managed to fix it.
Instead of activating the session before setting the relevant properties, I tried doing it afterwards, and it seems to work correctly.