我能够接收新的呼叫推送通知并报告呼叫,但是当应用处于终止状态时,我没有收到通知,而我仅错过了呼叫。
在我用来处理新的呼叫推送通知的代码下面:
- (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();});
}
问题可能在代码的最后一行。您在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(); // <-----
}];
根据您的评论,我们确定正确调用了didReceiveIncomingPushWithPayload
,因此显然已正确设置了推送通知。
这里发生了一件事情,这可能是导致您错过呼叫通知的原因,而不是让电话正常通过的原因:在报告来电后[self.cxProvider reportNewIncomingCallWithUUID:self.uuid update:callUpdate completion:^(NSError *error)
您直接使用[
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");
});