当通话是视频时,在 CallKit 来电屏幕中显示视频按钮

Display video button in CallKit incoming call screen when call is video

我正在使用以下代码接收视频通话。我的应用程序具有音频和视频通话功能,我正在使用 linphone + CallKit。

- (void)config {
    CXProviderConfiguration *config = [[CXProviderConfiguration alloc]
                                       initWithLocalizedName:[NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleName"]];
    config.ringtoneSound = @"notes_of_the_optimistic.caf";

    config.supportsVideo = TRUE;

    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.provider = [[CXProvider alloc] initWithConfiguration:config];
    [self.provider setDelegate:self queue:dispatch_get_main_queue()];
}



- (void)reportIncomingCall:(LinphoneCall *) call withUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video
{
    CXCallUpdate *update = [[CXCallUpdate alloc] init];
    update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:handle];
    update.supportsDTMF = TRUE;
    update.supportsHolding = TRUE;
    update.supportsGrouping = TRUE;
    update.supportsUngrouping = TRUE;
    update.hasVideo = video;
    linphone_call_ref(call);
    // Report incoming call to system
    LOGD(@"CallKit: report new incoming call");

    [self.provider reportNewIncomingCallWithUUID:uuid
                                          update:update
                                      completion:^(NSError *error) {
                                          if (error) {
                                              LOGE(@"CallKit: cannot complete incoming call from [%@] caused by [%@]",handle,[error localizedDescription]);
                                              if (   [error code] == CXErrorCodeIncomingCallErrorFilteredByDoNotDisturb
                                                  || [error code] == CXErrorCodeIncomingCallErrorFilteredByBlockList) {
                                                  linphone_call_decline(call,LinphoneReasonBusy); /*to give a chance for other devices to answer*/
                                              } else {
                                                  linphone_call_decline(call,LinphoneReasonUnknown);
                                              }
                                          }
                                          linphone_call_unref(call);
                                      }];
}

请查看随附的来电视频截图UI。它为音频和视频通话显示相同的 UI(按钮)。当通话是视频时,我想显示一个视频通话按钮。可以使用 CallKit 吗?如果可能,需要做出哪些改变?提前致谢。

不,很遗憾,无法自定义 CallKit 来电 UI。这就是为什么像 WhatsApp 这样的应用程序使用推送通知来通知视频通话,而不是依赖 CallKit 的原因。

请查看此演示。 CallKit 有一个 属性 supportsVideo of CXProviderConfiguration 和一个 属性 hasVideo of CXHandle。 它对我来说很好用。检查下面的演示 link.

https://websitebeaver.com/callkit-swift-tutorial-super-easy

func setupVdeoCall() {
        let config = CXProviderConfiguration(localizedName: "My App")
        config.iconTemplateImageData = UIImagePNGRepresentation(UIImage(named: "pizza")!)
        config.ringtoneSound = "ringtone.caf"
        config.includesCallsInRecents = false;
        config.supportsVideo = true;
        let provider = CXProvider(configuration: config)
        provider.setDelegate(self, queue: nil)
        let update = CXCallUpdate()
        update.remoteHandle = CXHandle(type: .generic, value: "Pete Za")
        update.hasVideo = true
        provider.reportNewIncomingCall(with: UUID(), update: update, completion: { error in })
    }

所以只需在 ProviderDelegate.swift 文件中修改如下。

    static var providerConfiguration: CXProviderConfiguration {
        let localizedName = NSLocalizedString("CallKitDemo", comment: "Name of application")
        let providerConfiguration = CXProviderConfiguration(localizedName: localizedName)

        providerConfiguration.supportsVideo = true. //For Video Call Enable
        
        providerConfiguration.includesCallsInRecents = false; //Show hide from phone recent call history
        
        providerConfiguration.maximumCallsPerCallGroup = 1

        providerConfiguration.supportedHandleTypes = [.phoneNumber]

        providerConfiguration.iconTemplateImageData = #imageLiteral(resourceName: "IconMask").pngData()

        providerConfiguration.ringtoneSound = "Ringtone.caf"
        
        return providerConfiguration
    }

和 reportIncomingCall()

func reportIncomingCall(uuid: UUID, handle: String, hasVideo: Bool = false, completion: ((NSError?) -> Void)? = nil) {
        // Construct a CXCallUpdate describing the incoming call, including the caller.
        let update = CXCallUpdate()
        update.remoteHandle = CXHandle(type: .phoneNumber, value: handle)
        update.hasVideo = hasVideo //For Video Call available or not

        // pre-heat the AVAudioSession
        //OTAudioDeviceManager.setAudioDevice(OTDefaultAudioDevice.sharedInstance())
        
        // Report the incoming call to the system
        provider.reportNewIncomingCall(with: uuid, update: update) { error in
            /*
                Only add incoming call to the app's list of calls if the call was allowed (i.e. there was no error)
                since calls may be "denied" for various legitimate reasons. See CXErrorCodeIncomingCallError.
             */
            if error == nil {
                let call = SpeakerboxCall(uuid: uuid)
                call.handle = handle

                self.callManager.addCall(call)
            }
            
            completion?(error as NSError?)
        }
    }