Ios 呼叫套件拒绝入站呼叫(目标-C)
我正在使用CallKit开发一个VOIP应用程序(我们称之为SampleApp),我正在努力解决一个问题 我可以使用CallKit以似乎正常工作的方式回答入站SampleApp调用。但是,当我拒绝一个调用时,调用仍然被实例化,这是不正确的行为 根据我的理解,我需要根据呼叫是否被接受和拒绝得到一个布尔值,然后用它来决定电话控制器是否接听来电 PhoneViewController.mIos 呼叫套件拒绝入站呼叫(目标-C),ios,objective-c,voip,callkit,Ios,Objective C,Voip,Callkit,我正在使用CallKit开发一个VOIP应用程序(我们称之为SampleApp),我正在努力解决一个问题 我可以使用CallKit以似乎正常工作的方式回答入站SampleApp调用。但是,当我拒绝一个调用时,调用仍然被实例化,这是不正确的行为 根据我的理解,我需要根据呼叫是否被接受和拒绝得到一个布尔值,然后用它来决定电话控制器是否接听来电 PhoneViewController.m - (void) presentIncomingCallAlertForCall:(SampleAppClient
- (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.
}
}
-(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];
}
- (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.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.
}
}
-(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];
}
- (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 {
...
}
}
这是我的第一个问题,我已经阅读了堆栈溢出指南,但是如果我做错了什么,请告诉我
但是,当我拒绝一个调用时,该调用无论如何都会被实例化,这
这是不正确的行为
不清楚您在这里的代码中试图做什么。您总是呼叫[自我应答呼叫]
(我们没有看到要执行的代码,但我假设它会向您的应用程序逻辑和后端报告用户已应答呼叫)就在[\pDelegate reportIncomingCall:…]
之后,因此您似乎假设用户已决定应答,甚至在用户做任何事情之前
相反,你应该告诉你的应用程序逻辑和你的后端,用户已经接听了电话,只有在你的-provider:performAnswerCallAction:
方法中,并且在你的-provider:performEndCallAction:
中,告诉你的应用程序逻辑和后端,用户已经拒绝了呼叫(如果是来电)
但是,当我拒绝一个调用时,该调用无论如何都会被实例化,这
这是不正确的行为
不清楚您在这里的代码中试图做什么。您总是呼叫[自我应答呼叫]
(我们没有看到要执行的代码,但我假设它会向您的应用程序逻辑和后端报告用户已应答呼叫)就在[\pDelegate reportIncomingCall:…]
之后,因此您似乎假设用户已决定应答,甚至在用户做任何事情之前
相反,你应该告诉你的应用程序逻辑和你的后端,用户已经接听了电话,只有在你的
-provider:performAnswerCallAction:
方法中,并且在你的-provider:performEndCallAction:
中,告诉你的应用程序逻辑和后端,用户已经拒绝了呼叫(如果是来电).以下是基于@user102008建议的解决方案,该建议实现了我想要实现的目标
我将应答传入呼叫的责任转移到提供者代理而不是phone view controller,后者调用应答呼叫或结束呼叫方法,具体取决于其提供者方法中的呼叫是被接受还是被拒绝
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.
}
}
-(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];
}
- (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];
}
下面是基于@user102008的建议的解决方案,它实现了我想要实现的目标 我将应答传入呼叫的责任转移到提供者代理而不是phone view controller,后者调用应答呼叫或结束呼叫方法,具体取决于其提供者方法中的呼叫是被接受还是被拒绝 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.
}
}
-(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];
}
- (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];
}
在
provider:performAnswerCallAction:
中,您是否尝试调用[action fail]
而不是fulfillWithDateConnected:
?@davewston感谢您的评论。我尝试了你的建议,但似乎没有效果。在提供程序:PerformancesWerCallAction:
中,你是否尝试调用[操作失败]
,而不是使用DateConnected:
实现?@Davewston感谢您的评论。我试过你的建议,但似乎没有效果。你的评论使我意识到我在倒退。My PhoneViewController(PVC)应接收呼叫,并将其报告给ProviderDelegate,并且该代理应在其自己的PerformancesWerCallAction和PerformanceCallAction中调用PVC的AnswerInMingCall方法。您的评论使我意识到我正在倒退。My PhoneViewController(PVC)应接收呼叫,并将其报告给ProviderDelegate,并且该代理应在其自己的PerformanceWerCallAction和PerformanceCallAction中调用PVC的AnswerInMingCall方法。