CXProviderDelegate方法未调用

时间:2018-09-27 04:32:21

标签: ios objective-c callkit

我的目标是在用户接听电话后打开我的CallViewController。我已经在这里阅读了一些摘录,可以使用以下方法完成:

- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action {
    NSLog(@"performAnswerCallAction");
}

- (void)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action {
     NSLog(@"performStartCallAction");
}

上面的代码在AppDelegate中。

但是,使用NSLogs根本不会触发此方法。我似乎找不到一些使用Objective-C实施的教程,这些教程对于初学者POV来说很容易理解。希望获得任何见解,谢谢!

1 个答案:

答案 0 :(得分:1)

首先,您是否设置了CXProvider的委托人?

let provider = CXProvider(configuration: your_call_kit_config)
provider.setDelegate(self, queue: nil) // 'nil' means it will run on main queue

还要使AppDelegate.swift文件符合CXProviderDelegate

当用户点击系统提供的来电屏幕上的“应答”按钮时,会呼叫

provider:performAnswerCallAction:。 (Apple文档HERE)。

provider:performStartCallAction:在成功请求CXCallController执行CXStartCallAction后被调用(Apple文档HERE)。

编辑:对于Objective-C

好吧,这里是Objective-C片段,例如,在AppDelegate中。首先,您需要使AppDelegate符合CXProviderDelegate,就像这样:

@interface AppDelegate () <CXProviderDelegate>

然后,为CXProviderCXCallController添加一个属性,如下所示:

@interface AppDelegate () <CXProviderDelegate>

@property (nonatomic, nonnull, strong) CXProvider *provider;
@property (nonatomic, nonnull, strong) CXCallController *callController;

@end

在AppDelegate的函数 application:willFinishLaunchingWithOptions:中,使用调用配置初始化CXProvider对象,如下所示:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Setup CallKit
    CXProviderConfiguration *providerConfiguration = [[CXProviderConfiguration alloc] initWithLocalizedName:@"MyApp"];
    providerConfiguration.supportsVideo = YES;
    providerConfiguration.includesCallsInRecents = YES;
    self.provider = [[CXProvider alloc] initWithConfiguration: providerConfiguration];

    // Since `AppDelegate` conforms to `CXProviderDelegate`, set it to the provider object
    // Setting 'nil' to `queue` argument means, that the methods will be executed on main thread.
    // Optionally, you can assign private serial queue to handle `CXProvider` method responses
    [self.provider setDelegate:self queue:nil];

    // Initialize `CallController`
    self.callController = [[CXCallController alloc] init];

    return YES;

}

并在 AppDelegate.m 文件的底部,实现CXProviderDelegate方法:

#pragma mark: - CXProvider delegate methods

- (void)providerDidReset:(CXProvider *)provider {
    // Drop all calls here (if there are pending)
}

/*!
 This method gets called when user presses on 'Accept' button on the incoming call screen provided by the system.
 Here you should configure `AVAudioSession` for VoIP calls and handle logic for answering the call.
 */
- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action {
    // Put your answering logic here
    // Note: It is important to fulfill the action inside the scope of it's function, or to fail, depending if error occured during answering
    [action fulfill];
}

/*!
 This method gets called when CXCallController object finishes the CXStartCallAction request. You need to request
 start call action to the CXCallController instance, when starting an outgoing VoIP call. After successful transaction,
 the provider will respond with this delegate method. Here you should also configure `AVAudioSession` for VoIP calls.
 */
- (void)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action {
    // Put your outgoing call action here
    // Note: It is important to fulfill the action inside the scope of it's function, or to fail, depending if error occured during starting a call
    [action fulfill];
}

要开始传出VoIP呼叫,您需要向CXCallController实例请求带有操作的事务,如下所示:

#pragma mark - Call Controller requests

- (void)startOutgoingVoIPCallWithNumber:(NSString *)number {
    NSUUID *callUUID = [NSUUID UUID]; // Here you create or assign UUID of call.
    CXHandle *callHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber value:number];
    CXStartCallAction *startCallAction = [[CXStartCallAction alloc] initWithCallUUID:callUUID handle:callHandle];
startCallAction.video = YES; // Yes or no is call is video or audio.

    CXTransaction *startCallTransaction = [[CXTransaction alloc] initWithAction:startCallAction];

    [self.callController requestTransaction:startCallTransaction completion:^(NSError * _Nullable error) {
        if (error) {
            // Handle start call error here
            // Ususally, error occurs if the system cannot handle the new outgoing call, since there are others pending
        }
        // If there is no error, CXProvider will respond with `provider:performStartCallAction:` method.
    }];
}

显示系统调用屏幕

#pragma mark - Report New incoming call

/*!
 You need to call this function each time you receive a new incoming call, usually right from the VoIP push notification.
 */
- (void)reportNewIncomingCallWithNumber:(NSString *)number {
    NSUUID *callUUID = [NSUUID UUID]; // Call UUID, you should have this in some Call object, not generating the new here
    CXHandle *callHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber value:number];
    CXCallUpdate *callInfo = [[CXCallUpdate alloc] init];
    callInfo.remoteHandle = callHandle;
    [self.provider reportNewIncomingCallWithUUID:[NSUUID UUID] update:callInfo completion:^(NSError * _Nullable error) {
        if (error) {
            // Handle error here
        }
        // If there is no error, system will display incoming call screen and when user taps on 'Answer',
        // `CXProvider` will respond with `provider:performAnswerCallAction:`
    }];
}
相关问题