【问题标题】:iOS VoIP calls not working when app in terminated state当应用程序处于终止状态时,iOS VoIP 呼叫不起作用
【发布时间】:2020-05-01 13:24:42
【问题描述】:

我能够收到新来电推送通知并报告来电,但是当应用程序处于终止状态时,我没有收到通知并且我只收到未接来电。

下面是我用来处理新来电推送通知的代码:

- (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();});
}

【问题讨论】:

  • 具体是什么不起作用?我的第一个出发点是:您是否确保正确设置了推送通知? didReceiveIncomingPushWithPayload 是否被调用?我也不太清楚您对CXEndCallAction 的请求放在代码中的什么位置。这绝对不应该是您的didReceiveIncomingPushWithPayload 的一部分。
  • 是的,我能够接收通知......和报告。当应用程序处于终止状态时,我只接到未接电话..不是电话..请帮助我
  • 这是 didReceieveIncomingPushWithPayload 所有我发布的代码的一部分..
  • @PashaMohamed 你找到解决方案了吗?

标签: xcode voip ios13 callkit pushkit


【解决方案1】:

问题可能出在代码的最后一行。您在dispatch_async 中调用完成块,因此它将在下一个运行循环中执行。问题是当应用程序处于终止状态时,您可能没有下一个运行循环。

尝试在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(); // <-----
}];

【讨论】:

  • 我修改了和你说的一样的代码..但仍然没有得到同样的问题没有接到电话..请帮助我
【解决方案2】:

根据您的 cmets,我们确定 didReceiveIncomingPushWithPayload 被正确调用,因此推送通知显然设置正确。

这里有一个问题,这可能是您收到未接电话通知的原因,而不是让电话正常进行的机会: 在报告来电后 [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 报告您有一个新的来电,然后仅在几毫秒后,在下一个主运行循环中,您报告远程方挂断了。这样的流程仅在远程方实际上同时挂断的情况下才有意义,例如因为连接设置太慢或者来电者很快又挂断了。但据我了解,这里(通常)不是这种情况。因此,我认为您不想在处理推送通知后不久向 iOS 报告呼叫已结束。如果您删除以下行,也许您可​​以尝试它是否有效:

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");
});

【讨论】:

  • 不,我没有收到任何错误.. 这样做时...请帮助
  • @PashaMohamed我也面临着和你一样的问题。当我在我的应用程序中进行 VOIP 呼叫时,如果我的应用程序在我直接收到呼叫时终止,则此委托方法 perform action: CXEndCallAction 将被调用。请提出任何解决方案。
猜你喜欢
  • 1970-01-01
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 2016-08-21
相关资源
最近更新 更多