diff --git a/MMPDeepSleepPreventer.m b/MMPDeepSleepPreventer.m index 81b2485..21d8f36 100644 --- a/MMPDeepSleepPreventer.m +++ b/MMPDeepSleepPreventer.m @@ -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 @@ -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 @@ -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 diff --git a/README.txt b/README.md similarity index 54% rename from README.txt rename to README.md index e9c247b..d73db27 100644 --- a/README.txt +++ b/README.md @@ -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.