diff --git a/JPSVolumeButtonHandler/JPSVolumeButtonHandler.h b/JPSVolumeButtonHandler/JPSVolumeButtonHandler.h index 81c9a10..acefc8d 100644 --- a/JPSVolumeButtonHandler/JPSVolumeButtonHandler.h +++ b/JPSVolumeButtonHandler/JPSVolumeButtonHandler.h @@ -23,6 +23,7 @@ typedef void (^JPSVolumeButtonBlock)(void); @property (nonatomic, strong) NSString * sessionCategory; @property (nonatomic, assign) AVAudioSessionCategoryOptions sessionOptions; +@property (nonatomic, strong) AVAudioSession * session; - (void)startHandler:(BOOL)disableSystemVolumeHandler; - (void)stopHandler; diff --git a/JPSVolumeButtonHandler/JPSVolumeButtonHandler.m b/JPSVolumeButtonHandler/JPSVolumeButtonHandler.m index caff513..1ccb5c1 100644 --- a/JPSVolumeButtonHandler/JPSVolumeButtonHandler.m +++ b/JPSVolumeButtonHandler/JPSVolumeButtonHandler.m @@ -12,15 +12,16 @@ // Comment/uncomment out NSLog to enable/disable logging #define JPSLog(fmt, ...) //NSLog(fmt, __VA_ARGS__) +#define volumeStep 0.06250f + static NSString *const sessionVolumeKeyPath = @"outputVolume"; static void *sessionContext = &sessionContext; -static CGFloat maxVolume = 0.99999f; -static CGFloat minVolume = 0.00001f; +static CGFloat maxVolume = 0.99999f - volumeStep; +static CGFloat minVolume = 0.00001f + volumeStep; @interface JPSVolumeButtonHandler () @property (nonatomic, assign) CGFloat initialVolume; -@property (nonatomic, strong) AVAudioSession * session; @property (nonatomic, strong) MPVolumeView * volumeView; @property (nonatomic, assign) BOOL appIsActive; @property (nonatomic, assign) BOOL isStarted; @@ -106,12 +107,12 @@ - (void)setupSession { withOptions:_sessionOptions error:&error]; if (error) { - NSLog(@"%@", error); + JPSLog(@"%@", error); return; } [self.session setActive:YES error:&error]; if (error) { - NSLog(@"%@", error); + JPSLog(@"%@", error); return; } @@ -157,7 +158,7 @@ - (void)audioSessionInterrupted:(NSNotification*)notification { NSError *error = nil; [self.session setActive:YES error:&error]; if (error) { - NSLog(@"%@", error); + JPSLog(@"%@", error); } break; } @@ -172,17 +173,23 @@ - (void)setInitialVolume { if (self.initialVolume > maxVolume) { self.initialVolume = maxVolume; self.isAdjustingInitialVolume = YES; - [self setSystemVolume:self.initialVolume]; + if (_volumeView) { + [self setSystemVolume:self.initialVolume]; + } } else if (self.initialVolume < minVolume) { self.initialVolume = minVolume; self.isAdjustingInitialVolume = YES; - [self setSystemVolume:self.initialVolume]; + if (_volumeView) { + [self setSystemVolume:self.initialVolume]; + } } } - (void)applicationDidChangeActive:(NSNotification *)notification { self.appIsActive = [notification.name isEqualToString:UIApplicationDidBecomeActiveNotification]; - if (self.appIsActive && self.isStarted) { + if (!self.isStarted) return; + if (!self.isAdjustingInitialVolume) return; + if (self.appIsActive ) { [self setInitialVolume]; } } @@ -202,13 +209,14 @@ + (instancetype)volumeButtonHandlerWithUpBlock:(JPSVolumeButtonBlock)upBlock dow - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == sessionContext) { + CGFloat oldVolume = [change[NSKeyValueChangeOldKey] floatValue]; + CGFloat newVolume = [change[NSKeyValueChangeNewKey] floatValue]; + JPSLog(@"Volume change detected: %f -> %f", oldVolume, newVolume); + if (!self.appIsActive) { // Probably control center, skip blocks return; } - - CGFloat newVolume = [change[NSKeyValueChangeNewKey] floatValue]; - CGFloat oldVolume = [change[NSKeyValueChangeOldKey] floatValue]; if (self.disableSystemVolumeHandler && newVolume == self.initialVolume) { // Resetting volume, skip blocks @@ -219,6 +227,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N return; } self.isAdjustingInitialVolume = NO; + return; } CGFloat difference = fabs(newVolume-oldVolume); @@ -245,7 +254,10 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N } // Reset volume - [self setSystemVolume:self.initialVolume]; + if (_volumeView) { + [self setSystemVolume:self.initialVolume]; + } + JPSLog(@"Restoring volume to %f (actual: %f)", self.initialVolume, self.session.outputVolume); } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } @@ -256,7 +268,10 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N - (void)setSystemVolume:(CGFloat)volume { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [[MPMusicPlayerController applicationMusicPlayer] setVolume:(float)volume]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[MPMusicPlayerController applicationMusicPlayer] setVolume:(float)volume]; + JPSLog(@"Changed volume to %f (actual: %f)", volume, self.session.outputVolume); + }); #pragma clang diagnostic pop }