addVolumeListener is not triggered on iOS 15 beta
Package: "react-native-system-setting": "1.7.6".
Platform: iOS
OS version: 15.0 beta
Issue:
SystemSetting.addVolumeListener listener is called when physical volume buttons are pressed on a device.
Follow the thread.
Also on iOS 15 official release addVolumeListener is NOT triggered when physical volume buttons are pressed on a device.
Package: "react-native-system-setting": "^1.7.6", "react-native": "^0.64.2",
Based on the following thread https://stackoverflow.com/questions/68249775/system-volume-change-observer-not-working-on-ios-15
I am testing the KVO method: in RTCSystemSetting.m Replace the following
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(volumeChanged:)
name:@"AVSystemController_SystemVolumeDidChangeNotification"
object:nil];
With:
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setActive:YES error:nil];
[audioSession addObserver:self
forKeyPath:@"outputVolume"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
Add:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
if (object == [AVAudioSession sharedInstance] && [keyPath isEqualToString:@"outputVolume"]) {
float newValue = [change[@"new"] floatValue];
//float old = [change[@"old"] floatValue];
if (hasListeners) {
[self sendEventWithName:@"EventVolume" body:@{@"value": [NSNumber numberWithFloat:newValue]}];
}
}
}
The above changes are based on https://stackoverflow.com/questions/43361599/react-native-catch-volume-buttons-press-not-for-volume-adjusting/43361738#43361738
Should work on iOS 15, but when the Volume is at max or min pressing the volume up or volume down button again will not trigger the event.
@EWTDTHK2 Thanks for your fix. It works, but I do get an error when long-pressing the volume button:
Illegal callback invocation from native module. This callback type only permits a single invocation from native code
I understand this problem, but don't know how to fix this, if anybody could help, that would be greatly appreciated.
@Vollkorn01 I tried to long press the physical button but I can't reproduce the error that you have encounter yet. However I double checked the original VolumeChanged code. It seems it need to check if the skipSetVolumeCount==0 to prevent setVolume method to trigger the event, perhaps it might be necessary to include this checking.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
if (object == [AVAudioSession sharedInstance] && [keyPath isEqualToString:@"outputVolume"]) {
float newValue = [change[@"new"] floatValue];
if (skipSetVolumeCount == 0 && hasListeners) {
[self sendEventWithName:@"EventVolume" body:@{@"value": [NSNumber numberWithFloat:newValue]}];
}
if (skipSetVolumeCount > 0) {
skipSetVolumeCount--;
}
}
}
Thanks for your quick reply @EWTDTHK2. I think it is actually related to another native module of mine, sorry for the confusion!
Is this still a problem in the final iOS 15 version?
yes
I have another issue: When putting the app to the background and opening it again, the listener won't get called anymore. I could reproduce the problem with a freshly initiated react native project. No error logs appear in XCode. Do you have the same problem @EWTDTHK2 ? Appreciate any leads..
I have another issue: When putting the app to the background and opening it again, the listener won't get called anymore. I could reproduce the problem with a freshly initiated react native project. No error logs appear in XCode. Do you have the same problem @EWTDTHK2 ? Appreciate any leads..
Didn't notice that until you pointed it out, thx for finding this problem. It seems I got the same issue also. I will see how to fix this.
In responds to @Vollkorn01 issue with app going to background and listener does not work when going back to foreground, I am testing the following changes, please kindly help to see if it works. Feel free to let me know if there are other issues. Replace:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(volumeChanged:)
name:@"AVSystemController_SystemVolumeDidChangeNotification"
object:nil];
With:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(addVolumeListener:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
Add:
- (void)addVolumeListener:(NSNotification *)notification {
NSLog(@"AddVolumeListener");
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setActive:YES error:nil];
[audioSession addObserver:self
forKeyPath:@"outputVolume"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
if (object == [AVAudioSession sharedInstance] && [keyPath isEqualToString:@"outputVolume"]) {
float newValue = [change[@"new"] floatValue];
if (skipSetVolumeCount == 0 && hasListeners) {
[self sendEventWithName:@"EventVolume" body:@{@"value": [NSNumber numberWithFloat:newValue]}];
}
if (skipSetVolumeCount > 0) {
skipSetVolumeCount--;
}
}
}
Have same issue,
tried @EWTDTHK2 solution, but facing a build error.

could be an outdated xcode?
Have same issue, tried @EWTDTHK2 solution, but facing a build error.
same issue. any solution for this
@AftabUfaq and @ionleu do you mind posting the full log of your compilation, I can't see which line the compiler shows where the error is located in this screen shot.
Same issue is happening with my project. Anyone resolved it yet?
@EWTDTHK2 check this
PS: Thank you for looking into that
Please try to add the following line:
#import <AVFoundation/AVFoundation.h>
below
#import <net/if.h>
see if it works?
@EWTDTHK2
Seems that now build process was successful, but still no effects, listener and getVolume is working only on Android
@EWTDTHK2
Seems that now build process was successful, but still no effects, listener and getVolume is working only on Android
by the way are you testing on simulator or real device? this only works on real device as far as I know it might not work on simulator.
@EWTDTHK2 ohh, testing on simulator, I'll test then on next week on real device. Thanks
@EWTDTHK2 Tested on iPhone 12, iOS: 15.0.2, works like a charm. Thank you for your help.
It works @EWTDTHK2!
Thank you so much for your fix @EWTDTHK2 , it worked! Another issue I recognized is, when audio is playing (spotify in my case) and I open the app with the fix, the music stops. Do you have the same issue?
Thank you so much for your fix @EWTDTHK2 , it worked! Another issue I recognized is, when audio is playing (spotify in my case) and I open the app with the fix, the music stops. Do you have the same issue?
I didn't test this yet, but I think it could likely have this issue. As both app trying to access the AVAudioSession resource. Did you try to disable this fix and see if the music would stops? If you go back to Spotify would you be able to start the music again?
@EWTDTHK2 Did you try to disable this fix and see if the music would stops? If I disable the fix, the music doesn't stop.
If you go back to Spotify would you be able to start the music again? Yes, If I go back to spotify, I can start the music again.
But if I'm in the app and pull down the drawer and press play, it doesn't play. So as long as I'm in the app, I cannot play music. But to be honest, this is not a big issue for our app.
There is another, more pressing issue for our app: The volume listener doesn't work, when the volume is at minimum or maximum value (and the down button / up button is pressed).
Thanks for your continuous improvements, very appreciated!
@EWTDTHK2 Did you try to disable this fix and see if the music would stops? If I disable the fix, the music doesn't stop.
If you go back to Spotify would you be able to start the music again? Yes, If I go back to spotify, I can start the music again.
But if I'm in the app and pull down the drawer and press play, it doesn't play. So as long as I'm in the app, I cannot play music. But to be honest, this is not a big issue for our app.
There is another, more pressing issue for our app: The volume listener doesn't work, when the volume is at minimum or maximum value (and the down button / up button is pressed). I haven't come up with a better solution to this issue yet. However, for our app, the volume is triggered by a photo taking remote control and fortunately, there are some bluetooth remote that would set vol up with one click and vol down with another click, which helped us to get around this issue.
Thanks for your continuous improvements, very appreciated! You are welcome.
Anyone merge this Pull Request to make this library work for ios 15 please?
vote for merging the PR https://github.com/c19354837/react-native-system-setting/pull/139 to let everybody use this fix. patch-package is not a pretty legit solution.
@c19354837 could you please check and merge or give some other contributors merge rights?
I'm late. I've publish 1.8.0-alpha.0, and you can install by npm install react-native-system-setting@alpha.