Search code examples
iosobjective-cvoipcallkit

How to reject incoming call programatically


I'm having a VoIP app in which calling works normally.

However, when we have an active VoIP call and the user receives a normal PSTN call, the active VoIP call goes blank - no audio is audible on either side.

To resolve this issue, we decided to end the new incoming call programmatically and I'm successfully able to detect an incoming PSTN call. But when I try to end the call, I get error saying:

EndCallAction transaction request failed: The operation couldn’t be completed. (com.apple.CallKit.error.requesttransaction error 4.)

Error code 4 refers to CXErrorCodeRequestTransactionErrorUnknownCallUUID.

Below is my code:

// called during initialization
self.callObserver = [[CXCallObserver alloc] init];
[self.callObserver setDelegate:self queue:dispatch_get_main_queue()];
- (void)callObserver:(nonnull CXCallObserver *)callObserver callChanged:(nonnull CXCall *)call {
    // isCallInProgress static variable tracks if a VoIP call is active and I verified its value - works as expected
    if(isCallInProgress) {
        if(!call.isOutgoing && !call.hasConnected && !call.hasEnded) {
            NSLog(@"*** New incoming call detected while a call is in progress - so reject it");
            dispatch_async(dispatch_get_main_queue(), ^{
                CXEndCallAction *endCallAction = [[CXEndCallAction alloc] initWithCallUUID:call.UUID];
                CXTransaction *transaction = [[CXTransaction alloc] initWithAction:endCallAction];

                CXCallController *controller = [[CXCallController alloc] init];
                [controller requestTransaction:transaction completion:^(NSError *error) {
                    if (error) {
                        NSLog(@"*** EndCallAction transaction request failed: %@", [error localizedDescription]);
                    }
                    else {
                        NSLog(@"*** EndCallAction transaction request successful");
                    }
                }];
            });
        }
    }
} 

What can I try next?


Solution

  • Just posting the solution which I decided to go ahead with and which solved the problem for us.

    I decided to listen for the AudioSession interruption which are triggered by the system based on what's happening with the device:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
    

    Following piece of code is specific to Twilio which solved the current call going blank while a new incoming call is ringing:

    - (void)handleInterruption:(NSNotification *)notification {
        if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
            if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
                self.audioDevice.block();
        }
    }