123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- //
- // WFCCallKitManager.m
- // WildFireChat
- //
- // Created by Rain on 2022/4/25.
- // Copyright © 2022 WildFireChat. All rights reserved.
- //
- #import "WFCCallKitManager.h"
- #if WFCU_SUPPORT_VOIP
- #import <CallKit/CallKit.h>
- #import <UIKit/UIKit.h>
- #import <WFChatUIKit/WFChatUIKit.h>
- @interface WFCCallKitManager ()
- @property(nonatomic, strong) CXProvider *provider;
- @property(nonatomic, strong) CXCallController *callController;
- @property(nonatomic, strong) NSMutableDictionary<NSString *, NSUUID *> *callUUIDDict;
- @end
- @implementation WFCCallKitManager
- - (instancetype)init {
- self = [super init];
- if(self) {
- #if USE_CALL_KIT
- self.callUUIDDict = [[NSMutableDictionary alloc] init];
- static CXProviderConfiguration* configInternal = nil;
- configInternal = [[CXProviderConfiguration alloc] initWithLocalizedName:@"野火"];
- configInternal.supportsVideo = true;
- configInternal.maximumCallsPerCallGroup = 1;
- configInternal.maximumCallGroups = 1;
- configInternal.supportedHandleTypes = [[NSSet alloc] initWithObjects:[NSNumber numberWithInt:CXHandleTypeGeneric],[NSNumber numberWithInt:CXHandleTypePhoneNumber], nil];
- UIImage* iconMaskImage = [UIImage imageNamed:@"file_icon"];
- configInternal.iconTemplateImageData = UIImagePNGRepresentation(iconMaskImage);
-
- self.provider = [[CXProvider alloc] initWithConfiguration: configInternal];
- [self.provider setDelegate:self queue:nil];
- self.callController = [[CXCallController alloc] initWithQueue:dispatch_get_main_queue()];
- #endif
- }
- return self;
- }
- - (void)didReceiveCall:(WFAVCallSession *)session {
- if(self.callUUIDDict[session.callId]) {
- session.callUUID = self.callUUIDDict[session.callId];
- } else {
- WFCCUserInfo *userInfo = [[WFCCIMService sharedWFCIMService] getUserInfo:session.initiator refresh:NO];
- NSUUID *currentCall = [NSUUID UUID];
- session.callUUID = currentCall;
- [self reportIncomingCallWithTitle:userInfo.displayName Sid:session.initiator audioOnly:session.audioOnly callId:session.callId uuid:currentCall];
- }
-
- }
- - (void)didCallEnded:(WFAVCallEndReason)reason duration:(int)callDuration {
- if([WFAVEngineKit sharedEngineKit].currentSession.callUUID) {
- CXEndCallAction *endAction = [[CXEndCallAction alloc] initWithCallUUID:[WFAVEngineKit sharedEngineKit].currentSession.callUUID];
- CXTransaction *transaction = [[CXTransaction alloc] initWithAction:endAction];
- [self.callController requestTransaction:transaction completion:^(NSError * _Nullable error) {
- NSLog(@"end call");
- }];
- }
- }
- - (void)didReceiveIncomingPushWithPayload:(PKPushPayload *)payload
- forType:(NSString *)type {
- NSLog(@"didReceiveIncomingPushWithPayload");
- NSDictionary *wfc = payload.dictionaryPayload[@"wfc"];
- if(wfc) {
- NSString *sender = wfc[@"sender"];
- NSString *pushData = wfc[@"pushData"];
- NSDictionary *pd = [NSJSONSerialization JSONObjectWithData:[pushData dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
- BOOL audioOnly = [pd[@"audioOnly"] boolValue];
- NSString *callId = pd[@"callId"];
- WFCCUserInfo *userInfo = [[WFCCIMService sharedWFCIMService] getUserInfo:sender refresh:NO];
- [self reportIncomingCallWithTitle:userInfo.displayName Sid:sender audioOnly:audioOnly callId:callId];
- }
- }
- - (void)reportIncomingCallWithTitle:(NSString *)title Sid:(NSString *)sid audioOnly:(BOOL)audioOnly callId:(NSString *)callId {
- NSUUID *currentCall = [NSUUID UUID];
- [self reportIncomingCallWithTitle:title Sid:sid audioOnly:audioOnly callId:callId uuid:currentCall];
- }
- - (void)reportIncomingCallWithTitle:(NSString *)title Sid:(NSString *)sid audioOnly:(BOOL)audioOnly callId:(NSString *)callId uuid:(NSUUID *)uuid {
- CXCallUpdate* update = [[CXCallUpdate alloc] init];
- update.supportsDTMF = false;
- update.supportsHolding = false;
- update.supportsGrouping = false;
- update.supportsUngrouping = false;
- update.hasVideo = !audioOnly;
- update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:sid];
- update.localizedCallerName = title;
-
- self.callUUIDDict[callId] = uuid;
- [[WFAVEngineKit sharedEngineKit] registerCall:callId uuid:uuid];
-
- [self.provider reportNewIncomingCallWithUUID:uuid update:update completion:^(NSError * _Nullable error) {
- if(error) {
- NSLog(@"error:%@", error);
- }
- }];
- }
- #pragma - mark CXProviderDelegate
- - (void)providerDidReset:(CXProvider *)provider {
- NSLog(@"providerDidReset");
- }
- - (void)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action {
- NSLog(@"performStartCallAction");
- }
- - (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action {
- NSLog(@"performAnswerCallAction");
- [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
- [[AVAudioSession sharedInstance] setMode:AVAudioSessionModeDefault error:nil];
- [action fulfill];
- }
- - (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action {
- NSLog(@"performEndCallAction");
- if([action.callUUID isEqual:[WFAVEngineKit sharedEngineKit].currentSession.callUUID]) {
- if ([WFAVEngineKit sharedEngineKit].currentSession.state != kWFAVEngineStateIdle) {
- [[WFAVEngineKit sharedEngineKit].currentSession endCall];
- }
- }
- [action fulfill];
- }
- - (void)provider:(CXProvider *)provider performSetMutedCallAction:(CXSetMutedCallAction *)action {
- if([action.callUUID isEqual:[WFAVEngineKit sharedEngineKit].currentSession.callUUID]) {
- if ([WFAVEngineKit sharedEngineKit].currentSession.state != kWFAVEngineStateIdle) {
- if (action.isMuted) {
- [[WFAVEngineKit sharedEngineKit].currentSession muteAudio:YES];
- } else {
- [[WFAVEngineKit sharedEngineKit].currentSession muteAudio:NO];
- }
- }
- }
- [action fulfill];
- }
- - (void)answerCall {
- [[WFAVEngineKit sharedEngineKit].currentSession answerCall:false callExtra:nil];
-
- UIViewController *videoVC;
- if ([WFAVEngineKit sharedEngineKit].currentSession.conversation.type == Group_Type && [WFAVEngineKit sharedEngineKit].supportMultiCall) {
- videoVC = [[WFCUMultiVideoViewController alloc] initWithSession:[WFAVEngineKit sharedEngineKit].currentSession];
- } else {
- videoVC = [[WFCUVideoViewController alloc] initWithSession:[WFAVEngineKit sharedEngineKit].currentSession];
- }
- if([[WFAVEngineKit sharedEngineKit].currentSession isAudioOnly]) {
- [[WFAVEngineKit sharedEngineKit].currentSession enableSpeaker:NO];
- } else {
- [[WFAVEngineKit sharedEngineKit].currentSession enableSpeaker:YES];
- }
- [[WFAVEngineKit sharedEngineKit] presentViewController:videoVC];
- }
- -(void)provider:(CXProvider *)provider didActivateAudioSession:(AVAudioSession *)audioSession {
- if ([WFAVEngineKit sharedEngineKit].currentSession.state == kWFAVEngineStateIncomming) {
- [self answerCall];
- } else {
- //有可能用户点击接听以后,IM服务消息还没有同步完成,来电消息还没有被处理,需要等待有来电session再接听.
- dispatch_async(dispatch_get_global_queue(0, 0), ^{
- int count = 60;
- while (count--) {
- [NSThread sleepForTimeInterval:0.05];
- if ([WFAVEngineKit sharedEngineKit].currentSession.state == kWFAVEngineStateIncomming) {
- dispatch_async(dispatch_get_main_queue(), ^{
- [self answerCall];
- });
- break;
- }
- }
- //3秒内没有接听成功,这里设置为失败
- [self.provider invalidate];
- });
- }
- }
- @end
- #endif
|