Lucas van Dongen
Lucas van Dongen

Reputation: 9848

iOS Callkit: CXProvider resets immediately after starting

I am converting an existing VoIP application to Callkit. I have a lot of code in place but somehow when I initialize the CXProvider it will call providerDidBegin and immediately after that it will call providerDidReset. It doesn't give a reason for that. I cannot register one of my outgoing phone calls after that because my provider isn't active.

I have tried looking into certificates, settings and so on but basically I don't need more than I already have for my VoIP app it seems.

The call from CallKit calling the reset method is the following:

CallKit`__42-[CXProvider handleConnectionInterruption]_block_invoke:

When I dig deeper where it comes from, it's NSXPCConnection related. What is this connection and how do I need to set it up?

Of course there is no interruption in the connection.

This is how I initialize my Delegate:

- (id)init {
    self = [super init];

    self.configuration = [[ProviderConfiguration alloc] init];
    self.provider = [[CXProvider alloc] initWithConfiguration:self.configuration];

    [self.provider setDelegate:self queue:dispatch_get_main_queue()];

    return self;
}

This is what the configuration looks like:

- (instancetype)init {
    self = [super initWithLocalizedName:@"MyCompany"];

    self.supportsVideo = NO;
    self.maximumCallsPerCallGroup = 1;
    self.supportedHandleTypes = [[NSSet alloc] initWithObjects:[NSNumber numberWithInt:(int)CXHandleTypePhoneNumber], nil];
    self.maximumCallGroups = 1;
    self.maximumCallsPerCallGroup = 5;


    return self;
}

Both callbacks are implemented:

- (void)providerDidBegin:(CXProvider *)provider {
    NSLog(@"Begun");
}

- (void)providerDidReset:(CXProvider *)provider {
    NSLog(@"Reset");
}

Upvotes: 6

Views: 5084

Answers (5)

João Vitor
João Vitor

Reputation: 240

You cannot use providerDidBegin to handle calls because it is used to identify the beginning of your class instance ProviderDelegate or the instance of CXProviderDelegate. To do the correct management you must create auxiliary classes that can do this for you.

See the example below from WWDC 2016: https://github.com/Lax/Learn-iOS-Swift-by-Examples/tree/master/Speakerbox

Upvotes: 0

user1763487
user1763487

Reputation: 474

I've got the same behavior on a simulator. On a device it was OK.

Upvotes: 0

Joe Tam
Joe Tam

Reputation: 622

Make sure you're calling reportNewIncomingCallWithUUID:update:completion with a valid, nonnull, UUID. Apple's current implementation calls completion with no error but no call screen is shown

Upvotes: 2

Vladimir Afinello
Vladimir Afinello

Reputation: 1271

In my case the same issue was due to missing VOIP background mode in Info.plist file

<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
    <string>voip</string>
</array>

XCode 9 doesn't allow to set this background mode using the Capabilities tab for some unknown reason.

Upvotes: 16

Lucas van Dongen
Lucas van Dongen

Reputation: 9848

Somehow these lines were the problem:

self.configuration = [[ProviderConfiguration alloc] init];
self.provider = [[CXProvider alloc] initWithConfiguration:self.configuration];

It got stored in self.configuration before calling init. By putting the same code there inline it worked.

CXProviderConfiguration *configuration = [[CXProviderConfiguration alloc] initWithLocalizedName:@"MyCompany"];

configuration.supportsVideo = NO;
configuration.supportedHandleTypes = [[NSSet alloc] initWithObjects:[NSNumber numberWithInt:(int)CXHandleTypePhoneNumber], nil];
configuration.maximumCallGroups = 1;
configuration.maximumCallsPerCallGroup = 5;
self.provider = [[CXProvider alloc] initWithConfiguration:configuration];

Upvotes: 1

Related Questions