By using one of the sample video calling app provided by Twilio (VideoCallKitQuickStart), I am trying to trigger an incoming call by sending a VoIP notification to the App. But the App doesn't trigger an incoming call. I also tried keeping the App opened while sending a VoIP notification and the App crashes, by throwing the below exception
NSInvalidArgumentException: Attempt to
insert non-property list object 'PKPushPayload: 0x16e44af0' for key
payload
Could someone, please help me or point me in the right direction on how to trigger an incoming call in the App, when a VoIP notification is received.
Below is my code in the ViewController.swift file
func pushRegistry(registry: PKPushRegistry!, didReceiveIncomingPushWithPayload payload: PKPushPayload!, forType type: String!) {
// Process the received push
self.reportIncomingCall(uuid: UUID(), roomName: "testRoom", completion: nil)
}
func reportIncomingCall(uuid: UUID, roomName: String?, completion: ((NSError?) -> Void)? = nil) {
let callHandle = CXHandle(type: .generic, value: roomName ?? "")
let callUpdate = CXCallUpdate()
callUpdate.remoteHandle = callHandle
callUpdate.supportsDTMF = false
callUpdate.supportsHolding = true
callUpdate.supportsGrouping = false
callUpdate.supportsUngrouping = false
callUpdate.hasVideo = true
callKitProvider.reportNewIncomingCall(with: uuid, update: callUpdate) { error in
if error == nil {
NSLog("Incoming call successfully reported.")
} else {
NSLog("Failed to report incoming call successfully: \(error?.localizedDescription).")
}
completion?(error as? NSError)
}
}
Posting late answer but it may helpful for someone.
Following code I did to handle voice incoming call.
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
NSLog("pushRegistry:didReceiveIncomingPushWithPayload:forType:")
print(payload)
if (type == PKPushType.voIP) {
TwilioVoice.handleNotification(payload.dictionaryPayload, delegate: self)
pushKitPushReceivedWithPayload(payload: payload)
}
}
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
NSLog("pushRegistry:didReceiveIncomingPushWithPayload:forType:completion:")
if (type == PKPushType.voIP) {
TwilioVoice.handleNotification(payload.dictionaryPayload, delegate: self)
pushKitPushReceivedWithPayload(payload: payload)
}
completion()
}
func pushKitPushReceivedWithPayload(payload: PKPushPayload){
if UIApplication.shared.applicationState != .active{
let msgType = payload.dictionaryPayload["twi_message_type"] as? String
if let messageType = msgType{
if messageType == "twilio.voice.call"{
fireLocalNotificationForVoiceCall(didStart: true)
}else if messageType == "twilio.voice.cancel"{
fireLocalNotificationForVoiceCall(didStart: false)
}
}
}
}
Below are the delegate methods of call kit I have added
extension AppDelegate : TVONotificationDelegate, TVOCallDelegate
{
func callInviteReceived(_ callInvite: TVOCallInvite)
{
if (callInvite.state == .pending)
{
//code
}
else if (callInvite.state == .canceled)
{
//code
}
}
func handleCallInviteReceived(_ callInvite: TVOCallInvite)
{
//code
}
func handleCallInviteCanceled(_ callInvite: TVOCallInvite)
{
//code
}
}
I have followed this tutorial provided by twilio - https://github.com/twilio/voice-quickstart-swift
Go through this tutorial and it will work.
Twilio developer evangelist here.
I'm not particularly good with iOS, but taking a quick look at the documentation for the PKPushRegistryDelegate
it looks like your pushRegistry
function definition isn't right.
It should be
func pushRegistry(_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
forType type: PKPushType)
That is, didReceiveIncomingPushWith
rather than didReceiveIncomingPushWithPayload
.
Alternatively, does it have anything to do with the fact that you're casting forType
to String
?
Swift 3.0
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {
NSLog("pushRegistry:didReceiveIncomingPushWithPayload:forType:")
if (type == PKPushType.voIP) {
print(payload.dictionaryPayload)
VoiceClient.sharedInstance().handleNotification(payload.dictionaryPayload, delegate: self)
}
}
And please don't make any changes in payload without modifying it in order for the SDK to extract the incoming call info out of the payload so that the SDK can notify the application with incoming calls