2

I am integrating CallKit with VOIP app. I was able to make incoming and outgoing calls. I followed the step:

  1. ConfigureAudioSession
  2. startAudio in (didActivate)
  3. stopAudio in (didDeActivate)

I have implemented the callbacks for DTMF provider delegate as shown below:

func provider(_ provider: CXProvider, perform action: CXPlayDTMFCallAction) {
    print("Provider - CXPlayDTMFCallAction")

    let dtmfDigts:String = action.digits

    for (index, _) in dtmfDigts.characters.enumerated() {
        let dtmfDigit = dtmfDigts.utf8CString[index]
        print("Processing dtmfDigit:\(dtmfDigit)" )
        self.softphone.dtmf(on:dtmfDigit)
    }

    self.softphone.dtmfOff()

    // Signal to the system that the action has been successfully performed.
    action.fulfill()
}

I don't hear key-press sound i.e., local dtmf sounds when I press a number on the native in-call UI during the call.

From https://developer.apple.com/reference/callkit/cxplaydtmfcallaction:

"CallKit automatically plays the corresponding DTMF frequencies for any digits transmitted over a call. The app is responsible for managing the timing and handling of digits as part of fulfilling the action."

Is this a known issue or callkit doesn't play the local dtmf key press sounds?

ssk
  • 9,045
  • 26
  • 96
  • 169
  • By "native dialer" are you referring to the 'Keypad' tab in the Phone app, or do you mean the 'keypad' button shown in the native in-call UI? – Stuart M Dec 14 '16 at 18:44
  • @StuartM yes, native in-call UI. – ssk Dec 14 '16 at 18:45
  • @ssk What is self.softphone and how it's implemented in ProviderDelegate.swift of callkit and how to send pressed digit on Custom Dialer UI for IVR handling. – Parth Barot Nov 18 '19 at 12:58
  • @ParthBarot elf.softphone is a wrapper to the PJSIP's pjsua library. – ssk Nov 18 '19 at 18:52

2 Answers2

3

CallKit should play the DTMF tones locally when pressing keys in the 'keypad' button of the native in-call UI. But a CallKit app is responsible for sending the DTMF tones over its own network interface to the remote side.

If you are not hearing the tones played locally from within the native in-call UI then please report a bug to Apple.

Stuart M
  • 11,458
  • 6
  • 45
  • 59
  • As far as I've read and trying to implement a VOIP call to an IVR system. On what basis is this method called? Let's say an IVR says please enter 4 after 1 beep. Will my app be notified after that 1 beep? – nr5 Jun 14 '19 at 09:56
3

I was able to make it work by:

func provider(_ provider: CXProvider, perform action: CXPlayDTMFCallAction) {
    print("Provider - CXPlayDTMFCallAction")

    self.softphone.audioController.configureAudioSession()

    let dtmfDigts:String = action.digits

    for (index, _) in dtmfDigts.characters.enumerated() {
        let dtmfDigit = dtmfDigts.utf8CString[index]
        print("Processing dtmfDigit:\(dtmfDigit)" )
        self.softphone.dtmf(on:dtmfDigit)
    }

    self.softphone.dtmfOff()

    // Signal to the system that the action has been successfully performed.
    action.fulfill()
}

Note: I added self.softphone.audioController.configureAudioSession().

-(void) configureAudioSession
{
    // Configure the audio session
    AVAudioSession *sessionInstance = [AVAudioSession sharedInstance];

    // we are going to play and record so we pick that category
    NSError *error = nil;
    [sessionInstance setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
    if (error) {
        NSLog(@"error setting audio category %@",error);
    }

    // set the mode to voice chat
    [sessionInstance setMode:AVAudioSessionModeVoiceChat error:&error];
    if (error) {
        NSLog(@"error setting audio mode %@",error);
    }

    NSLog(@"setupAudioSession");

    return;
}
ssk
  • 9,045
  • 26
  • 96
  • 169
  • What is self.softphone and how it's implemented in ProviderDelegate.swift of callkit and how to send pressed digit on Custom Dialer UI for IVR handling. – Parth Barot Nov 18 '19 at 12:23