CallKit:如何区分拒绝呼叫和结束连接呼叫
CallKit: how to differentiate between decline call and end connected call
假设一个应用程序同时支持两个调用。第一个电话接通,第二个电话打进来。一个人得到 "end call & answer call"、"decline"、"hold call and answer call" 按钮。
如果是"end call & answer call",则表示结束已接通的电话,接听新的电话。
"decline"表示拒接来电
在这两种情况下,代表
- (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action
被触发。现在,应该如何知道要结束这些呼叫中的哪一个,是来电还是已接通的呼叫? CXEndCallAction
没有说明 "decline" 或 "end-already-connected call"
的原因
有人有解决办法吗?
您需要访问 CXEndCallAction 的 callUUID 成员。
交易是在正确的对象上调用的,因此您只需终止与传输的 UUID 匹配的调用。这意味着您必须将对 UUID 的支持添加到您自己的调用对象模型中。
我发现有一个交易列表委托:
- (BOOL)provider:(CXProvider *)provider executeTransaction:(CXTransaction *)transaction
如果有交易会触发其他委托,例如 CXSetHeldCallAction
或 CXEndCallAction
,则实施此委托将提供足够的信息。所以现在我可以决定触发什么操作,并在必要时绕过其他代表。
如果其他人正在苦苦挣扎,这是我的代码:
- (BOOL)provider:(CXProvider *)provider executeTransaction:(CXTransaction *)transaction
{
NSLog(@"executeTransaction : %@", transaction.debugDescription);
BOOL callEnd = NO;
BOOL callHold= NO;
BOOL callAnswer = NO;
NSPredicate *filter = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [CXEndCallAction class]];
NSArray *ends = [transaction.actions filteredArrayUsingPredicate:filter];
callEnd = [ends count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [CXAnswerCallAction class]];
NSArray *answer = [transaction.actions filteredArrayUsingPredicate:filter];
callAnswer = [answer count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [CXSetHeldCallAction class]];
NSArray *hold = [transaction.actions filteredArrayUsingPredicate:filter];
callHold = [hold count] >= 1;
if(callEnd && callAnswer)
{
actionType = kCallKitEndAndAnswer;
[[MyCallManager sharedManager] endPreviousCallAndAnswerNewCall:^(BOOL succeeded) {
NSLog(@"end answered call: %@", succeeded ? @"yes" : @"No");
CXEndCallAction *en = [ends firstObject];
succeeded ? [en fulfill] : [en fail];
CXAnswerCallAction *an= [answer firstObject];
succeeded ? [an fulfill] : [an fail];
}];
return YES;
}
else if(callHold && callAnswer)
{
actionType = kCallKitHoldAndAnswer;
[[MyCallManager sharedManager] answerCall:^(BOOL succeeded) {
NSLog(@"hold answered call: %@", succeeded ? @"yes" : @"No");
CXSetHeldCallAction *ho = [hold firstObject];
succeeded ? [ho fulfill] : [ho fail];
CXAnswerCallAction *an= [answer firstObject];
succeeded ? [an fulfill] : [an fail];
}];
return YES;
}
else if([hold count] == 2)
{
[[MyCallManager sharedManager] swapCalls];
usleep(25000);
CXSetHeldCallAction * fi = [hold firstObject];
CXSetHeldCallAction * la = [hold lastObject];
[fi fulfill];
[la fulfill];
return YES;
}
return NO;
}
您可以使用枚举和 "isMemberOfClass"。
在providerDelegate.h
// Call Modes.
typedef NS_ENUM(NSUInteger, CallMode) {
kUnknownMode = 0,
kEndAndAnswerMode = 1,
kHoldAndAnswerMode = 2
};
在providerDelegate.m
@property(nonatomic, assign) CallMode mode;
并添加以下代码以获取每笔交易。
- (BOOL)provider:(CXProvider *)provider executeTransaction:(CXTransaction *)transaction {
NSLog(@"Provider execute transaction");
BOOL callEnd = NO;
BOOL callHold= NO;
BOOL callAnswer = NO;
NSPredicate *filter = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [CXEndCallAction class]];
NSArray<CXEndCallAction *> *ends = [transaction.actions filteredArrayUsingPredicate:filter];
callEnd = [ends count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [CXAnswerCallAction class]];
NSArray<CXAnswerCallAction *> *answers = [transaction.actions filteredArrayUsingPredicate:filter];
callAnswer = [answers count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [CXSetHeldCallAction class]];
NSArray<CXSetHeldCallAction *> *holds = [transaction.actions filteredArrayUsingPredicate:filter];
callHold = [holds count] >= 1;
if(callEnd && callAnswer) {
_mode = kEndAndAnswerMode;
} else if(callHold && callAnswer) {
_mode = kHoldAndAnswerMode;
} else {
_mode = kUnknownMode;
}
return NO;
}
假设一个应用程序同时支持两个调用。第一个电话接通,第二个电话打进来。一个人得到 "end call & answer call"、"decline"、"hold call and answer call" 按钮。
如果是"end call & answer call",则表示结束已接通的电话,接听新的电话。 "decline"表示拒接来电
在这两种情况下,代表
- (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action
被触发。现在,应该如何知道要结束这些呼叫中的哪一个,是来电还是已接通的呼叫? CXEndCallAction
没有说明 "decline" 或 "end-already-connected call"
有人有解决办法吗?
您需要访问 CXEndCallAction 的 callUUID 成员。
交易是在正确的对象上调用的,因此您只需终止与传输的 UUID 匹配的调用。这意味着您必须将对 UUID 的支持添加到您自己的调用对象模型中。
我发现有一个交易列表委托:
- (BOOL)provider:(CXProvider *)provider executeTransaction:(CXTransaction *)transaction
如果有交易会触发其他委托,例如 CXSetHeldCallAction
或 CXEndCallAction
,则实施此委托将提供足够的信息。所以现在我可以决定触发什么操作,并在必要时绕过其他代表。
如果其他人正在苦苦挣扎,这是我的代码:
- (BOOL)provider:(CXProvider *)provider executeTransaction:(CXTransaction *)transaction
{
NSLog(@"executeTransaction : %@", transaction.debugDescription);
BOOL callEnd = NO;
BOOL callHold= NO;
BOOL callAnswer = NO;
NSPredicate *filter = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [CXEndCallAction class]];
NSArray *ends = [transaction.actions filteredArrayUsingPredicate:filter];
callEnd = [ends count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [CXAnswerCallAction class]];
NSArray *answer = [transaction.actions filteredArrayUsingPredicate:filter];
callAnswer = [answer count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [CXSetHeldCallAction class]];
NSArray *hold = [transaction.actions filteredArrayUsingPredicate:filter];
callHold = [hold count] >= 1;
if(callEnd && callAnswer)
{
actionType = kCallKitEndAndAnswer;
[[MyCallManager sharedManager] endPreviousCallAndAnswerNewCall:^(BOOL succeeded) {
NSLog(@"end answered call: %@", succeeded ? @"yes" : @"No");
CXEndCallAction *en = [ends firstObject];
succeeded ? [en fulfill] : [en fail];
CXAnswerCallAction *an= [answer firstObject];
succeeded ? [an fulfill] : [an fail];
}];
return YES;
}
else if(callHold && callAnswer)
{
actionType = kCallKitHoldAndAnswer;
[[MyCallManager sharedManager] answerCall:^(BOOL succeeded) {
NSLog(@"hold answered call: %@", succeeded ? @"yes" : @"No");
CXSetHeldCallAction *ho = [hold firstObject];
succeeded ? [ho fulfill] : [ho fail];
CXAnswerCallAction *an= [answer firstObject];
succeeded ? [an fulfill] : [an fail];
}];
return YES;
}
else if([hold count] == 2)
{
[[MyCallManager sharedManager] swapCalls];
usleep(25000);
CXSetHeldCallAction * fi = [hold firstObject];
CXSetHeldCallAction * la = [hold lastObject];
[fi fulfill];
[la fulfill];
return YES;
}
return NO;
}
您可以使用枚举和 "isMemberOfClass"。
在providerDelegate.h
// Call Modes.
typedef NS_ENUM(NSUInteger, CallMode) {
kUnknownMode = 0,
kEndAndAnswerMode = 1,
kHoldAndAnswerMode = 2
};
在providerDelegate.m
@property(nonatomic, assign) CallMode mode;
并添加以下代码以获取每笔交易。
- (BOOL)provider:(CXProvider *)provider executeTransaction:(CXTransaction *)transaction {
NSLog(@"Provider execute transaction");
BOOL callEnd = NO;
BOOL callHold= NO;
BOOL callAnswer = NO;
NSPredicate *filter = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [CXEndCallAction class]];
NSArray<CXEndCallAction *> *ends = [transaction.actions filteredArrayUsingPredicate:filter];
callEnd = [ends count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [CXAnswerCallAction class]];
NSArray<CXAnswerCallAction *> *answers = [transaction.actions filteredArrayUsingPredicate:filter];
callAnswer = [answers count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [CXSetHeldCallAction class]];
NSArray<CXSetHeldCallAction *> *holds = [transaction.actions filteredArrayUsingPredicate:filter];
callHold = [holds count] >= 1;
if(callEnd && callAnswer) {
_mode = kEndAndAnswerMode;
} else if(callHold && callAnswer) {
_mode = kHoldAndAnswerMode;
} else {
_mode = kUnknownMode;
}
return NO;
}