Video-Calling icon indicating copy to clipboard operation
Video-Calling copied to clipboard

receiving a call in the background iOS

Open hamza1216 opened this issue 3 years ago • 2 comments

Hello. I am trying to implement background call using agora. I used pushkit and voip to receiving a call in the background, and getting a call. But when I accept a call, it's crashing. I am sharing my code and need help.

------------- Sending Part -------------------

appleCallKit.startOutgoingCall(of: targetUserId)
SendVOIPPush(devicetoken, callerName, callerUUID) // sending voip push message so that user can get notification in the background

------------- Receiving Part -----------------

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
        print("###### PushRegistry IncomingPush #########")
        let dict = payload.dictionaryPayload
        let uuid = dict["uuid"] as! String
        let caller_name = dict["caller_name"] as! String
        if UIApplication.shared.applicationState == .active {
            
        } else {
            showIncomingCall(of: uuid, withUserName: caller_name)
        }
    }
func showIncomingCall(of session: String, withUserName username: String) {
        let callUpdate = CXCallUpdate()
        callUpdate.remoteHandle = CXHandle(type: .phoneNumber, value: session)
        callUpdate.localizedCallerName = username
        callUpdate.hasVideo = true
        callUpdate.supportsDTMF = false
        
        let uuid = pairedUUID(of: session)
        
        provider.reportNewIncomingCall(with: uuid, update: callUpdate, completion: { error in
            if let error = error {
                print("reportNewIncomingCall error: \(error.localizedDescription)")
            }
        })
    }

func callCenter(_ callCenter: CallCenter, answerCall session: String) {
        print("callCenter answerCall")
                
        guard let inviter = AgoraRtm.shared().inviter else {
            fatalError("rtm inviter nil")
        }
        
        guard let channel = inviter.lastIncomingInvitation?.content else {
            fatalError("lastIncomingInvitation content nil")
        }
        
        guard let remote = UInt(session) else {
            fatalError("string to int fail")
        }
        
        inviter.accpetLastIncomingInvitation()
        
        // present VideoChat VC after 'callCenterDidActiveAudioSession'
        self.prepareToVideoChat = { [weak self] in
            var data: (channel: String, remote: UInt)
            data.channel = channel
            data.remote = remote
            self?.navigateVideoCall(data: data)
            //self?.performSegue(withIdentifier: "DialToVideoChat", sender: data)
        }
    }

So when user sends a call, it calls both startOutgooingCall function and an api to send push notification. And in the receiving part, I called the reportNewIncomingCall in the pushRegistry so that can get incoming call. So far it's ok. And when I accept the call, callCenter answrCall delegate is being called. but the inviter.lastIncomingInvitation is nil and it's crashing. I am not able to get channel name because the inviter.lastIncomingInvitation is nil. I would appreciate if someone could help me. Thanks.

hamza1216 avatar Aug 07 '21 17:08 hamza1216

Hello. I am trying to implement background call using agora. I used pushkit and voip to receiving a call in the background, and getting a call. But when I accept a call, it's crashing. I am sharing my code and need help.

------------- Sending Part -------------------

appleCallKit.startOutgoingCall(of: targetUserId)
SendVOIPPush(devicetoken, callerName, callerUUID) // sending voip push message so that user can get notification in the background

------------- Receiving Part -----------------

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
        print("###### PushRegistry IncomingPush #########")
        let dict = payload.dictionaryPayload
        let uuid = dict["uuid"] as! String
        let caller_name = dict["caller_name"] as! String
        if UIApplication.shared.applicationState == .active {
            
        } else {
            showIncomingCall(of: uuid, withUserName: caller_name)
        }
    }
func showIncomingCall(of session: String, withUserName username: String) {
        let callUpdate = CXCallUpdate()
        callUpdate.remoteHandle = CXHandle(type: .phoneNumber, value: session)
        callUpdate.localizedCallerName = username
        callUpdate.hasVideo = true
        callUpdate.supportsDTMF = false
        
        let uuid = pairedUUID(of: session)
        
        provider.reportNewIncomingCall(with: uuid, update: callUpdate, completion: { error in
            if let error = error {
                print("reportNewIncomingCall error: \(error.localizedDescription)")
            }
        })
    }

func callCenter(_ callCenter: CallCenter, answerCall session: String) {
        print("callCenter answerCall")
                
        guard let inviter = AgoraRtm.shared().inviter else {
            fatalError("rtm inviter nil")
        }
        
        guard let channel = inviter.lastIncomingInvitation?.content else {
            fatalError("lastIncomingInvitation content nil")
        }
        
        guard let remote = UInt(session) else {
            fatalError("string to int fail")
        }
        
        inviter.accpetLastIncomingInvitation()
        
        // present VideoChat VC after 'callCenterDidActiveAudioSession'
        self.prepareToVideoChat = { [weak self] in
            var data: (channel: String, remote: UInt)
            data.channel = channel
            data.remote = remote
            self?.navigateVideoCall(data: data)
            //self?.performSegue(withIdentifier: "DialToVideoChat", sender: data)
        }
    }

So when user sends a call, it calls both startOutgooingCall function and an api to send push notification. And in the receiving part, I called the reportNewIncomingCall in the pushRegistry so that can get incoming call. So far it's ok. And when I accept the call, callCenter answrCall delegate is being called. but the inviter.lastIncomingInvitation is nil and it's crashing. I am not able to get channel name because the inviter.lastIncomingInvitation is nil. I would appreciate if someone could help me. Thanks.

Hi Can you please share sample project files to [email protected]. It may helpful to me.

yashwanth8803 avatar Sep 23 '21 05:09 yashwanth8803

@hamza1216 can you please send me sample code for this SendVOIPPush(devicetoken, callerName, callerUUID)

GireshD avatar Oct 13 '22 06:10 GireshD