Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

addVolumeListener is not triggered on iOS 15 beta #134

Open
badrey opened this issue Sep 20, 2021 · 33 comments
Open

addVolumeListener is not triggered on iOS 15 beta #134

badrey opened this issue Sep 20, 2021 · 33 comments

Comments

@badrey
Copy link

badrey commented Sep 20, 2021

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.

@gitmazzio
Copy link

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",

@EWTDTHK2
Copy link

EWTDTHK2 commented Oct 3, 2021

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.

@Vollkorn01
Copy link

@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.

@EWTDTHK2
Copy link

EWTDTHK2 commented Oct 4, 2021

@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--;
        }
    }
}

@Vollkorn01
Copy link

Thanks for your quick reply @EWTDTHK2. I think it is actually related to another native module of mine, sorry for the confusion!

@pke
Copy link

pke commented Oct 5, 2021

Is this still a problem in the final iOS 15 version?

@normenster
Copy link

yes

@Vollkorn01
Copy link

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..

@EWTDTHK2
Copy link

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.

@EWTDTHK2
Copy link

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--;
        }
    }
}

@ionleu
Copy link

ionleu commented Oct 19, 2021

Have same issue,
tried @EWTDTHK2 solution, but facing a build error.
Screen Shot 2021-10-19 at 3 15 56 PM

@pke
Copy link

pke commented Oct 20, 2021

could be an outdated xcode?

@AftabUfaq
Copy link

Have same issue,
tried @EWTDTHK2 solution, but facing a build error.
Screen Shot 2021-10-19 at 3 15 56 PM

same issue. any solution for this

@EWTDTHK2
Copy link

@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.

@redefinered
Copy link

Same issue is happening with my project. Anyone resolved it yet?

@ionleu
Copy link

ionleu commented Oct 25, 2021

error build.pdf

@EWTDTHK2 check this

PS: Thank you for looking into that

@EWTDTHK2
Copy link

error build.pdf

@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?

@ionleu
Copy link

ionleu commented Oct 26, 2021

@EWTDTHK2

Seems that now build process was successful, but still no effects, listener and getVolume is working only on Android

@EWTDTHK2
Copy link

@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.

@ionleu
Copy link

ionleu commented Oct 29, 2021

@EWTDTHK2 ohh, testing on simulator, I'll test then on next week on real device. Thanks

@ionleu
Copy link

ionleu commented Nov 2, 2021

@EWTDTHK2 Tested on iPhone 12, iOS: 15.0.2, works like a charm. Thank you for your help.

@gitmazzio
Copy link

It works @EWTDTHK2!

@Vollkorn01
Copy link

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?

@EWTDTHK2
Copy link

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?

@Vollkorn01
Copy link

Vollkorn01 commented Nov 17, 2021

@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
Copy link

@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.

@SpQuyt
Copy link

SpQuyt commented Dec 20, 2021

Anyone merge this Pull Request to make this library work for ios 15 please?

@kot331107
Copy link

vote for merging the PR #139 to let everybody use this fix. patch-package is not a pretty legit solution.

@pke
Copy link

pke commented Feb 16, 2022

@c19354837 could you please check and merge or give some other contributors merge rights?

c19354837 added a commit that referenced this issue Feb 16, 2022
[FIX] #134 addVolumeListener is not triggered on iOS 15
@c19354837
Copy link
Owner

I'm late. I've publish 1.8.0-alpha.0, and you can install by npm install react-native-system-setting@alpha.

@stereodenis
Copy link

@c19354837 your listener triggered on every second time. So, now there are some skips

@arjun-mavonic
Copy link

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--;
        }
    }
}

@EWTDTHK2 , Thanks you solution really helped. But every time my apps goes into background and then foreground, It's creating more listeners.

INFO  Volume button pressed {"value": 0.949999988079071} 0.949999988079071
INFO  Volume button pressed {"value": 0.949999988079071} 0.949999988079071
INFO  Volume button pressed {"value": 0.949999988079071} 0.949999988079071
INFO  Volume button pressed {"value": 0.949999988079071} 0.949999988079071
INFO  Volume button pressed {"value": 1} 1
INFO  Volume button pressed {"value": 1} 1
INFO  Volume button pressed {"value": 1} 1
INFO  Volume button pressed {"value": 1} 1

@dquessenberry
Copy link

@c19354837 do you plan to publish a new version with this fix? It's been a while, so I'm just curious. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests