react-native-system-setting icon indicating copy to clipboard operation
react-native-system-setting copied to clipboard

addVolumeListener is not triggered on iOS 15 beta

Open badrey opened this issue 4 years ago • 33 comments

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.

badrey avatar Sep 20 '21 18:09 badrey

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

gitmazzio avatar Sep 27 '21 07:09 gitmazzio

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 avatar Oct 03 '21 16:10 EWTDTHK2

@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 avatar Oct 04 '21 14:10 Vollkorn01

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

EWTDTHK2 avatar Oct 04 '21 17:10 EWTDTHK2

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

Vollkorn01 avatar Oct 05 '21 09:10 Vollkorn01

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

pke avatar Oct 05 '21 22:10 pke

yes

normenster avatar Oct 06 '21 15:10 normenster

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

Vollkorn01 avatar Oct 08 '21 16:10 Vollkorn01

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 avatar Oct 16 '21 17:10 EWTDTHK2

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 avatar Oct 16 '21 20:10 EWTDTHK2

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

ionleu avatar Oct 19 '21 19:10 ionleu

could be an outdated xcode?

pke avatar Oct 20 '21 22:10 pke

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

AftabUfaq avatar Oct 21 '21 13:10 AftabUfaq

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

EWTDTHK2 avatar Oct 23 '21 15:10 EWTDTHK2

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

redefinered avatar Oct 25 '21 10:10 redefinered

error build.pdf

@EWTDTHK2 check this

PS: Thank you for looking into that

ionleu avatar Oct 25 '21 21:10 ionleu

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?

EWTDTHK2 avatar Oct 25 '21 23:10 EWTDTHK2

@EWTDTHK2

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

ionleu avatar Oct 26 '21 20:10 ionleu

@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 avatar Oct 28 '21 17:10 EWTDTHK2

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

ionleu avatar Oct 29 '21 00:10 ionleu

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

ionleu avatar Nov 02 '21 18:11 ionleu

It works @EWTDTHK2!

gitmazzio avatar Nov 09 '21 11:11 gitmazzio

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?

Vollkorn01 avatar Nov 12 '21 16:11 Vollkorn01

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 avatar Nov 12 '21 18:11 EWTDTHK2

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

Vollkorn01 avatar Nov 17 '21 16:11 Vollkorn01

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

EWTDTHK2 avatar Nov 17 '21 17:11 EWTDTHK2

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

SpQuyt avatar Dec 20 '21 08:12 SpQuyt

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.

kot331107 avatar Feb 16 '22 01:02 kot331107

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

pke avatar Feb 16 '22 08:02 pke

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

c19354837 avatar Feb 16 '22 14:02 c19354837