CallKit 拒绝来电 (Objective-C)
CallKit Reject Inbound Call (Objective-C)
我正在使用 CallKit 开发一个 VOIP 应用程序(我们称之为 SampleApp),但遇到了一个问题。
我可以使用 CallKit 以一种看起来可以正常工作的方式接听入站 SampleApp 呼叫。但是,当我拒绝呼叫时,无论如何都会实例化呼叫,这是不正确的行为。
根据我的理解,我需要根据呼叫是否被接受和拒绝以某种方式获得一个布尔值,然后使用它来决定 phone 控制器是否接听来电。
PhoneViewController.m
- (void) presentIncomingCallAlertForCall:(SampleAppClientCall*)call
{
callIdentifier = [[NSUUID alloc] init];
// Use CallKit if iPhone
if(UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad)
{
[_pDelegate reportIncomingCall:callIdentifier
handle:call.remoteAddress
hasVideo:hasVideo
completionHandler: nil];
[self answerIncomingCall];
}
// Use Notification mechanism if iPad
else
{
// etc.
}
}
ProviderDelegate.m
-(void) reportIncomingCall: (NSUUID *) uuid
handle: (NSString *) handle
hasVideo: (BOOL) hasVideo
completionHandler:
(nullable void (^) (NSArray * _Nullable results, NSError * _Nonnull error))completionHandler
{
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber
value:handle];
update.hasVideo = hasVideo;
[provider reportNewIncomingCallWithUUID:uuid
update:update
completion: ^(NSError *error)
{
// not sure what to put here?
}];
}
- (void) provider: (CXProvider *)provider
performAnswerCallAction : (CXAnswerCallAction *)action
{
NSDate *now = [[NSDate alloc] init];
[action fulfillWithDateConnected: now];
}
这是我的第一个问题,我已经阅读了 Stack Overflow 指南,但如果我做错了什么请告诉我。
However, when I reject a call, the call is instantiated anyway, which
is incorrect behaviour.
不清楚您在此处的代码中试图做什么。您总是在 [_pDelegate reportIncomingCall:...]
之后立即调用 [self answerIncomingCall];
(我们看不到代码,但我假设向您的应用程序逻辑和后端报告用户已接听电话),所以看起来就像你假设用户已经决定回答它,甚至在用户做任何事情之前。
相反,您应该告诉您的应用程序逻辑和后端用户已接听电话,仅在您的 -provider:performAnswerCallAction:
方法和 -provider:performEndCallAction:
中,告诉您的应用程序逻辑和您的后端表明用户已拒绝来电(如果来电正在响铃)。
这是基于@user102008 的建议的解决方案,它实现了我想要实现的目标。
我将接听来电的责任移交给了提供者委托,而不是 phone 视图控制器,它会根据在其提供者方法。
PhoneViewController.m
- (void) presentIncomingCallAlertForCall:(SampleAppClientCall*)call {
callIdentifier = [[NSUUID alloc] init];
// Use CallKit if iPhone
if(UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
[_pDelegate reportIncomingCall:callIdentifier
handle:call.remoteAddress
hasVideo:hasVideo
completionHandler: nil];
}
// Use Notification mechanism if iPad
else {
...
}
}
ProviderDelegate.h
-(void) reportIncomingCall: (NSUUID *) uuid
handle: (NSString *) handle
hasVideo: (BOOL) hasVideo
completionHandler: (nullable void (^) (NSArray * _Nullable results, NSError * _Nonnull error))
completionHandler {
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber value:handle];
update.hasVideo = hasVideo;
[provider reportNewIncomingCallWithUUID:uuid
update:update
completion: ^(NSError *error) {
if (error) {
[self reportCallEnded:uuid reason:(NSInteger *)CXCallEndedReasonFailed];
}
}];
}
- (void) provider: (CXProvider *)provider performAnswerCallAction: (CXAnswerCallAction *)action {
[_phoneVC answerIncomingCall];
NSDate *now = [[NSDate alloc] init];
[action fulfillWithDateConnected: now];
}
- (void) provider: (CXProvider *)provider performEndCallAction: (CXEndCallAction *)action {
[_phoneVC rejectIncomingCall];
NSDate *now = [[NSDate alloc] init];
[action fulfillWithDateEnded: now];
}
我正在使用 CallKit 开发一个 VOIP 应用程序(我们称之为 SampleApp),但遇到了一个问题。
我可以使用 CallKit 以一种看起来可以正常工作的方式接听入站 SampleApp 呼叫。但是,当我拒绝呼叫时,无论如何都会实例化呼叫,这是不正确的行为。
根据我的理解,我需要根据呼叫是否被接受和拒绝以某种方式获得一个布尔值,然后使用它来决定 phone 控制器是否接听来电。
PhoneViewController.m
- (void) presentIncomingCallAlertForCall:(SampleAppClientCall*)call
{
callIdentifier = [[NSUUID alloc] init];
// Use CallKit if iPhone
if(UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad)
{
[_pDelegate reportIncomingCall:callIdentifier
handle:call.remoteAddress
hasVideo:hasVideo
completionHandler: nil];
[self answerIncomingCall];
}
// Use Notification mechanism if iPad
else
{
// etc.
}
}
ProviderDelegate.m
-(void) reportIncomingCall: (NSUUID *) uuid
handle: (NSString *) handle
hasVideo: (BOOL) hasVideo
completionHandler:
(nullable void (^) (NSArray * _Nullable results, NSError * _Nonnull error))completionHandler
{
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber
value:handle];
update.hasVideo = hasVideo;
[provider reportNewIncomingCallWithUUID:uuid
update:update
completion: ^(NSError *error)
{
// not sure what to put here?
}];
}
- (void) provider: (CXProvider *)provider
performAnswerCallAction : (CXAnswerCallAction *)action
{
NSDate *now = [[NSDate alloc] init];
[action fulfillWithDateConnected: now];
}
这是我的第一个问题,我已经阅读了 Stack Overflow 指南,但如果我做错了什么请告诉我。
However, when I reject a call, the call is instantiated anyway, which is incorrect behaviour.
不清楚您在此处的代码中试图做什么。您总是在 [_pDelegate reportIncomingCall:...]
之后立即调用 [self answerIncomingCall];
(我们看不到代码,但我假设向您的应用程序逻辑和后端报告用户已接听电话),所以看起来就像你假设用户已经决定回答它,甚至在用户做任何事情之前。
相反,您应该告诉您的应用程序逻辑和后端用户已接听电话,仅在您的 -provider:performAnswerCallAction:
方法和 -provider:performEndCallAction:
中,告诉您的应用程序逻辑和您的后端表明用户已拒绝来电(如果来电正在响铃)。
这是基于@user102008 的建议的解决方案,它实现了我想要实现的目标。
我将接听来电的责任移交给了提供者委托,而不是 phone 视图控制器,它会根据在其提供者方法。
PhoneViewController.m
- (void) presentIncomingCallAlertForCall:(SampleAppClientCall*)call {
callIdentifier = [[NSUUID alloc] init];
// Use CallKit if iPhone
if(UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
[_pDelegate reportIncomingCall:callIdentifier
handle:call.remoteAddress
hasVideo:hasVideo
completionHandler: nil];
}
// Use Notification mechanism if iPad
else {
...
}
}
ProviderDelegate.h
-(void) reportIncomingCall: (NSUUID *) uuid
handle: (NSString *) handle
hasVideo: (BOOL) hasVideo
completionHandler: (nullable void (^) (NSArray * _Nullable results, NSError * _Nonnull error))
completionHandler {
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber value:handle];
update.hasVideo = hasVideo;
[provider reportNewIncomingCallWithUUID:uuid
update:update
completion: ^(NSError *error) {
if (error) {
[self reportCallEnded:uuid reason:(NSInteger *)CXCallEndedReasonFailed];
}
}];
}
- (void) provider: (CXProvider *)provider performAnswerCallAction: (CXAnswerCallAction *)action {
[_phoneVC answerIncomingCall];
NSDate *now = [[NSDate alloc] init];
[action fulfillWithDateConnected: now];
}
- (void) provider: (CXProvider *)provider performEndCallAction: (CXEndCallAction *)action {
[_phoneVC rejectIncomingCall];
NSDate *now = [[NSDate alloc] init];
[action fulfillWithDateEnded: now];
}