Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 81 additions & 65 deletions MMPDeepSleepPreventer.m
Original file line number Diff line number Diff line change
Expand Up @@ -81,27 +81,17 @@ - (id)init
// Set up audio player with sound file
audioPlayer_ = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
error:nil];
[fileURL release];

[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];
self.audioPlayer.volume = 0.1;
self.audioPlayer.numberOfLoops = -1;

return self;
}


- (void)dealloc
{
[preventSleepTimer_ release];
[audioPlayer_ release];

[super dealloc];
}


#pragma mark -
#pragma mark Public Methods

Expand All @@ -120,7 +110,6 @@ - (void)startPreventSleep
userInfo:nil
repeats:YES];
self.preventSleepTimer = preventSleepTimer;
[preventSleepTimer release];

// Add the timer to the current run loop.
[[NSRunLoop currentRunLoop] addTimer:self.preventSleepTimer
Expand All @@ -146,57 +135,84 @@ - (void)mmp_playPreventSleepSound

- (void)mmp_setUpAudioSession
{
// Initialize audio session
AudioSessionInitialize
(
NULL, // Use NULL to use the default (main) run loop.
NULL, // Use NULL to use the default run loop mode.
NULL, // A reference to your interruption listener callback function.
// See “Responding to Audio Session Interruptions” in Apple's "Audio Session Programming Guide" for a description of how to write
// and use an interruption callback function.
NULL // Data you intend to be passed to your interruption listener callback function when the audio session object invokes it.
);

// Activate audio session
OSStatus activationResult = 0;
activationResult = AudioSessionSetActive(true);

if (activationResult)
{
MMPDLog(@"AudioSession is active");
}

// Set up audio session category to kAudioSessionCategory_MediaPlayback.
// While playing sounds using this session category at least every 10 seconds, the iPhone doesn't go to sleep.
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback; // Defines a new variable of type UInt32 and initializes it with the identifier
// for the category you want to apply to the audio session.
AudioSessionSetProperty
(
kAudioSessionProperty_AudioCategory, // The identifier, or key, for the audio session property you want to set.
sizeof(sessionCategory), // The size, in bytes, of the property value that you are applying.
&sessionCategory // The category you want to apply to the audio session.
);

// Set up audio session playback mixing behavior.
// kAudioSessionCategory_MediaPlayback usually prevents playback mixing, so we allow it here. This way, we don't get in the way of other sound playback in an application.
// This property has a value of false (0) by default. When the audio session category changes, such as during an interruption, the value of this property reverts to false.
// To regain mixing behavior you must then set this property again.

// Always check to see if setting this property succeeds or fails, and react appropriately; behavior may change in future releases of iPhone OS.
OSStatus propertySetError = 0;
UInt32 allowMixing = true;

propertySetError = AudioSessionSetProperty
(
kAudioSessionProperty_OverrideCategoryMixWithOthers, // The identifier, or key, for the audio session property you want to set.
sizeof(allowMixing), // The size, in bytes, of the property value that you are applying.
&allowMixing // The value to apply to the property.
);

if (propertySetError)
{
MMPALog(@"Error setting kAudioSessionProperty_OverrideCategoryMixWithOthers: %d", propertySetError);
}
// AudioSession functions are deprecated from iOS 7.0, so prefer using AVAudioSession
AVAudioSession *audioSession = [AVAudioSession sharedInstance];

if ([audioSession respondsToSelector:@selector(setCategory:withOptions:error:)]) {
NSError *activeSetError = nil;
[audioSession setActive:YES
error:&activeSetError];

if (activeSetError) {
MMPALog(@"Error activating AVAudioSession: %@", activeSetError);
}

NSError *categorySetError = nil;
[audioSession setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionMixWithOthers
error:&categorySetError];

if (categorySetError) {
MMPALog(@"Error setting AVAudioSession category: %@", categorySetError);
}
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // supress deprecated warning

// Initialize audio session
AudioSessionInitialize
(
NULL, // Use NULL to use the default (main) run loop.
NULL, // Use NULL to use the default run loop mode.
NULL, // A reference to your interruption listener callback function.
// See “Responding to Audio Session Interruptions” in Apple's "Audio Session Programming Guide" for a description of how to write
// and use an interruption callback function.
NULL // Data you intend to be passed to your interruption listener callback function when the audio session object invokes it.
);

// Activate audio session
OSStatus activationResult = 0;
activationResult = AudioSessionSetActive(true);

if (activationResult)
{
MMPDLog(@"AudioSession is active");
}

// Set up audio session category to kAudioSessionCategory_MediaPlayback.
// While playing sounds using this session category at least every 10 seconds, the iPhone doesn't go to sleep.
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback; // Defines a new variable of type UInt32 and initializes it with the identifier
// for the category you want to apply to the audio session.
AudioSessionSetProperty
(
kAudioSessionProperty_AudioCategory, // The identifier, or key, for the audio session property you want to set.
sizeof(sessionCategory), // The size, in bytes, of the property value that you are applying.
&sessionCategory // The category you want to apply to the audio session.
);

// Set up audio session playback mixing behavior.
// kAudioSessionCategory_MediaPlayback usually prevents playback mixing, so we allow it here. This way, we don't get in the way of other sound playback in an application.
// This property has a value of false (0) by default. When the audio session category changes, such as during an interruption, the value of this property reverts to false.
// To regain mixing behavior you must then set this property again.

// Always check to see if setting this property succeeds or fails, and react appropriately; behavior may change in future releases of iPhone OS.
OSStatus propertySetError = 0;
UInt32 allowMixing = true;

propertySetError = AudioSessionSetProperty
(
kAudioSessionProperty_OverrideCategoryMixWithOthers, // The identifier, or key, for the audio session property you want to set.
sizeof(allowMixing), // The size, in bytes, of the property value that you are applying.
&allowMixing // The value to apply to the property.
);

if (propertySetError)
{
MMPALog(@"Error setting kAudioSessionProperty_OverrideCategoryMixWithOthers: %ld", propertySetError);
}

#pragma clang diagnostic pop
}
}

@end
57 changes: 32 additions & 25 deletions README.txt → README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
Description:
MMPDeepSleepPreventer is an Objective-C class used to prevent iOS devices from deep sleeping.
This has been tested on an iOS versions 3.0 to 4.2.1, so far and should work on all devices,
running one of these iOS versions.

MMPDeepSleepPreventer is released under the New BSD License. (Below is the exact license text).
If you use this code a little attribution note would be greatly appreciated.


How-To Use:
- Add MMPDeepSleepPreventer.h and MMPDeepSleepPreventer.m as well as
MMPSilence.wav to your project.
- Add “AVFoundation.framework” and “AudioToolbox.framework” to your project.
- Import MMPDeepSleepPreventer.h where you want to use the class.
- Instantiate an MMPDeepSleepPreventer object.
- Use -[MMPDeepSleepPreventer startPreventSleep]
and -[MMPDeepSleepPreventer stopPreventSleep] when needed.


Inspired by:
Some question on stackoverflow.com
Some posts on Apple's devforums.


License:
Description
----------
MMPDeepSleepPreventer is an Objective-C class used to prevent iOS devices from deep sleeping.
This has been tested on an iOS versions 3.0 to 5.0, so far and should work on all devices running one of these iOS versions.

MMPDeepSleepPreventer is released under the New BSD License. (Below is the exact license text).
If you use this code a little attribution note would be greatly appreciated.


How-To Use
----------
- Add MMPDeepSleepPreventer.h and MMPDeepSleepPreventer.m as well as
MMPSilence.wav to your project.
- Add “AVFoundation.framework” and “AudioToolbox.framework” to your project.
- Add `audio` to the array for the `UIBackgroundModes` key in your Info.plist
- Import MMPDeepSleepPreventer.h where you want to use the class.
- Instantiate an MMPDeepSleepPreventer object.
- Use -[MMPDeepSleepPreventer startPreventSleep]
and -[MMPDeepSleepPreventer stopPreventSleep] when needed. Do this before the app actually moves to background.

App Store compatibility
-----------------------
As of August 2012, setting the `audio` flag in `UIBackgroundModes` when you are, in fact, not playing any audible audio is likely to get your app rejected.

Inspired by
-----------
- Some question on stackoverflow.com
- Some posts on Apple's devforums.


License
-------
Copyright (c) 2009-2011, Marco Peluso - marcopeluso.com
All rights reserved.

Expand Down