Сбой исходящего сотового вызова при входящем вызове VoIP в iOS 13

Я реализовал CallKit для аудио- и видеозвонков с помощью VoIP PushKit в iOS, и он отлично работает в iOS 12 и предыдущих версиях, а также нормально работает в iOS 13 и 13.1.

Но он не работает в двух сценариях:

1) Наше приложение находится на переднем плане. Когда выполняется сотовый вызов и получен VoIP push, экран входящего вызова для набора вызовов отображается в течение 5–10 секунд, а затем как сотовые, так и VOIP-вызовы завершаются ошибкой с предупреждением «Call Failed».

2) Наше приложение находится в фоновом или заблокированном состоянии. Когда сотовый вызов выполняется и получен VoIP push, то и сотовые, и VOIP-вызовы завершаются ошибкой с предупреждением «Call Failed». На этот раз интерфейс входящего вызова не отображается.

Я показываю здесь свой код:

- (void)registerAppForVOIPPush {

    PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
    pushRegistry.delegate = self;
    pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}

Затем нажмите делегатов

#pragma mark PKPushRegistryDelegate ----

- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials: (PKPushCredentials *)credentials forType:(NSString *)type {

    NSString *newToken = [self hexadecimalStringFromData:credentials.token];
    //Make a note of this token to a server to send VOIP for a particular device
    NSLog(@"VOIP token ::: %@", newToken);
    _voipToken = newToken;
}

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type {
    //available(iOS, introduced: 8.0, deprecated: 11.0)
    [self pushRegistryDidReceivedPushWithPayload:payload forType:type withCompletionHandler:NULL];
}

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
    //available(iOS 11.0, *)
    [self pushRegistryDidReceivedPushWithPayload:payload forType:type withCompletionHandler:completion];
}

- (void)pushRegistryDidReceivedPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {

    //Call kit configration
    CXProviderConfiguration *providerConfig = [[CXProviderConfiguration alloc] initWithLocalizedName:@"my app Call"];
    providerConfig.supportsVideo = NO;
    providerConfig.maximumCallGroups = 1;
    providerConfig.maximumCallsPerCallGroup = 1;
    providerConfig.supportedHandleTypes = [[NSSet alloc] initWithObjects:[NSNumber numberWithInteger:CXHandleTypeGeneric], nil];
    providerConfig.iconTemplateImageData = UIImagePNGRepresentation([UIImage imageNamed:@"IconMask"]);


    CXProvider *provider = [[CXProvider alloc] initWithConfiguration:providerConfig];
    [provider setDelegate:self queue:nil];

    //generate token
    NSUUID *callbackUUIDToken = [NSUUID UUID];

    //Display callkit

    NSString *uniqueIdentifier = @"Max test";
    CXCallUpdate *update = [[CXCallUpdate alloc] init];
    update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:uniqueIdentifier];
    update.supportsGrouping = FALSE;
    update.supportsUngrouping = FALSE;
    update.supportsHolding = FALSE;
    update.localizedCallerName = uniqueIdentifier;
    update.hasVideo = NO;
    [provider reportNewIncomingCallWithUUID:callbackUUIDToken update:update completion:^(NSError * _Nullable error) {
        NSLog(@"reportNewIncomingCallWithUUID error: %@",error);
    }];

    if (completion) {
        dispatch_async(dispatch_get_main_queue(), ^{
            completion();
        });
    }
}

Я отлично реализовал метод делегата CXProvider

- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action{
    [action fulfill];
}

- (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action{
    [action fulfill];
}

а также управлял другими методами делегата для управления вызовом и всем остальным, и он отлично работает в любых условиях.

Я проверил эти два сценария с другими приложениями, такими как Google Duo, Whatsapp и FaceTime, и он правильно показывает CallKit без сбоев, но в моем приложении он не работает. Я понятия не имею, где он терпит неудачу.

Итак, у меня есть две указанные проблемы для iOS 13 и более поздних версий. Любая помощь будет оценена по достоинству. Спасибо.


person Max    schedule 26.09.2019    source источник


Ответы (2)


Вероятно, это ошибка iOS 13, и, если вы еще этого не сделали, вам следует сообщить об этом в Apple.

Я думаю, что причина, по которой работают такие приложения, как Whatapp (и то, которое я разрабатываю), заключается в том, что мы создаем приложение с использованием iOS 12 SDK. Мы делаем это из-за ограничений push-уведомлений VoIP, представленных в iOS 13. Таким образом, вы можете попытаться обойти проблему - по крайней мере до апреля 2020 года - используя iOS 12 SDK. Надеюсь, Apple скоро исправит эту проблему.

person Marco    schedule 26.09.2019
comment
Хорошо, я проверю это, а также проверю, влияет ли это на изменения пользовательского интерфейса для поддержки iOS 13 или нет. - person Max; 27.09.2019
comment
@ Макс, ты добился успеха? - person Rushang Prajapati; 27.09.2019
comment
@RushangPrajapati, Да, это сработало, и я добился успеха в своих определенных проблемах. - person Max; 27.09.2019
comment
@Max, Привет Макс, ты решил свою проблему, у меня такая же проблема .. - person Steven; 07.10.2019
comment
@Steven, проблема в последней версии iOS или xcode 11, поэтому я создал приложение из xcode 10.2.1, и оно отлично работает. Нам нужно дождаться более новой версии iOS или xcode, в которой они исправят эту проблему. - person Max; 09.10.2019
comment
@Steven, я также проверил это с помощью xcode 11.1, и, наконец, я построил с более низкой версией xcode, которая отлично работает. - person Max; 09.10.2019
comment
@Max Все было хорошо, но теперь я не могу получать VOIP после X раз. Пожалуйста, изучите мой вопрос и помогите мне, если сможете. stackoverflow.com/questions/63673548/ - person Rushang Prajapati; 04.09.2020

@Max Я столкнулся с той же проблемой, с которой вы столкнулись в iOS версии 13.0–13.2.0.

Как многие разработчики сообщили об этой проблеме в Apple. В последней версии iOS, выпущенной на прошлой неделе (iOS 13.2.2), эта ошибка исправлена. Итак, теперь вместо сборки из более старого SDK вы можете начать работать с последним SDK и xCode 11.2.1.

person Mehul Thakkar    schedule 13.11.2019
comment
Хорошо, спасибо за обновление. Я проверю с последней версией Xcode. - person Max; 13.11.2019