iOS VoIP звонки не работают, когда приложение находится в завершенном состоянии - PullRequest
0 голосов
/ 01 мая 2020

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

Ниже код, который я использую для обработки нового вызова pu sh уведомление:

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {

    NSString * nameA = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"]
    CXProviderConfiguration *config = [[CXProviderConfiguration alloc]initWithLocalizedName:nameA];
    config.supportsVideo = FALSE;
    config.iconTemplateImageData = UIImagePNGRepresentation([UIImage imageNamed:@"callkit_logo"]);

    NSArray *ar = @[ [NSNumber numberWithInt:(int)CXHandleTypeGeneric] ];
    NSSet *handleTypes = [[NSSet alloc] initWithArray:ar];
    [config setSupportedHandleTypes:handleTypes];
    [config setMaximumCallGroups:2];
    [config setMaximumCallsPerCallGroup:1];

    self.cxProvider = [[CXProvider alloc] initWithConfiguration:config];

    NSDictionary *dict = [payload.dictionaryPayload objectForKey:@"aps"];
    NSString * callm = [dict objectForKey:@"callfrom"];
    if (callm.length == 0) {
        callm = @"CALL BB";
    }
    CXHandle *callHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:callm];
    CXCallUpdate *callUpdate = [[CXCallUpdate alloc] init];
    callUpdate.remoteHandle = callHandle;
    callUpdate.supportsDTMF = YES;
    callUpdate.supportsHolding = YES;
    callUpdate.supportsGrouping = NO;
    callUpdate.supportsUngrouping = NO;
    callUpdate.hasVideo = NO;

    self.uuid = [NSUUID UUID];

    [self.cxProvider reportNewIncomingCallWithUUID:self.uuid update:callUpdate completion:^(NSError *error) {
        NSLog(@"error1 ----> %@",error);
        if (error) {
            if (@available(iOS 13.0, *)) {
                [self.cxProvider reportCallWithUUID:self.uuid endedAtDate:[NSDate now] reason:CXCallEndedReasonFailed];
            } else {
            }
        }
    }];
    CXCallController *callController = [[CXCallController alloc] initWithQueue:dispatch_get_main_queue()]; 
    dispatch_async(dispatch_get_main_queue(), ^{

        CXEndCallAction *endCallAction = [[CXEndCallAction alloc] initWithCallUUID:self.uuid];
        CXTransaction *transaction = [[CXTransaction alloc] initWithAction:endCallAction];

        [callController requestTransaction:transaction completion:^(NSError *error) {
            NSLog(@"error2 ----> %@",error);
            if (@available(iOS 13.0, *)) {
                [self.cxProvider reportCallWithUUID:self.uuid endedAtDate:[NSDate now] reason:CXCallEndedReasonRemoteEnded];
            } else {
            }
        }];
    });

    [self processPush:payload.dictionaryPayload];
    dispatch_async(dispatch_get_main_queue(), ^{completion();});
}

Ответы [ 2 ]

0 голосов
/ 04 мая 2020

Из ваших комментариев мы установили, что didReceiveIncomingPushWithPayload вызывается правильно, поэтому уведомления pu sh, по-видимому, были настроены правильно.

Одна вещь здесь неактуальна, и это может быть причиной того, что вы получили уведомления о пропущенных вызовах вместо возможности пропустить вызов go в обычном режиме: сообщив о входящем вызове с помощью [self.cxProvider reportNewIncomingCallWithUUID:self.uuid update:callUpdate completion:^(NSError *error), вы напрямую сообщаете об окончании вызова на iOS с помощью

CXEndCallAction *endCallAction = [[CXEndCallAction alloc] initWithCallUUID:self.uuid];
        CXTransaction *transaction = [[CXTransaction alloc] initWithAction:endCallAction];

        [callController requestTransaction:transaction completion:^(NSError *error)

Это не должно в таком случае: вы по существу сообщаете iOS сначала, что у вас есть новый входящий вызов, а затем только через миллисекунды, при следующем основном запуске l oop, вы сообщаете, что удаленная сторона повесила трубку. Такой поток будет иметь смысл только в сценарии ios, где удаленная сторона фактически зависает в это время, например, из-за того, что установка соединения слишком медленная или вызывающий абонент снова очень быстро зависает. Но из того, что я понял, это не (как правило) дело здесь. Поэтому я думаю, что вы не захотите сообщать о завершении вызова на iOS вскоре после обработки уведомления pu sh. Может быть, вы можете попробовать, если это работает, если вы удалите следующие строки:

CXCallController *callController = [[CXCallController alloc] initWithQueue:dispatch_get_main_queue()]; 
    dispatch_async(dispatch_get_main_queue(), ^{

        CXEndCallAction *endCallAction = [[CXEndCallAction alloc] initWithCallUUID:self.uuid];
        CXTransaction *transaction = [[CXTransaction alloc] initWithAction:endCallAction];

        [callController requestTransaction:transaction completion:^(NSError *error) {
            NSLog(@"error2 ----> %@",error);
            if (@available(iOS 13.0, *)) {
                [self.cxProvider reportCallWithUUID:self.uuid endedAtDate:[NSDate now] reason:CXCallEndedReasonRemoteEnded];
            } else {
            }
        }];

    });

Еще одна вещь, которую я хотел бы исследовать: есть ли сообщение об ошибке, которое дает какие-либо подсказки в исходной отчетности в [self.cxProvider reportNewIncomingCallWithUUID:self.uuid update:callUpdate completion:^(NSError *error)?

Наконец, я бы посоветовал проверить, что ваш обработчик завершения действительно вызывается в конце, установив точку останова или добавив регистратор в

dispatch_async(dispatch_get_main_queue(), ^{
    completion();
    NSLog(@"completion handler called");
});
0 голосов
/ 04 мая 2020

Проблема может быть в последней строке вашего кода. Вы вызываете блок завершения внутри dispatch_async, поэтому он будет выполнен при следующем запуске -l oop. Проблема в том, что когда приложение находится в состоянии завершения, у вас, вероятно, нет следующего запуска-l oop.

Попытайтесь вызвать блок завершения внутри блока завершения reportNewIncomingCallWithUUID:

[self.cxProvider reportNewIncomingCallWithUUID:self.uuid update:callUpdate completion:^(NSError *error) {
        NSLog(@"error1 ----> %@",error);
        if (error) {
            if (@available(iOS 13.0, *)) {
                [self.cxProvider reportCallWithUUID:self.uuid endedAtDate:[NSDate now] reason:CXCallEndedReasonFailed];
            } else {
            }
        }
        completion(); // <-----
}];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...