Giter Site home page Giter Site logo

Comments (38)

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024 1

I tried calling directly the Apple APNS

curl -v \
-d '{"aps":{"alert":"Test","badge":42}, "data": {"Username": "Alex", "ConnectionId": "Alex123"}}' \
-H "apns-topic: com.appbundle.local.voip" \
-H "apns-push-type: voip" \
-H "apns-priority: 10" \
--http2 \
--cert VOIP-local.pem \
https://api.development.push.apple.com/3/device/{token}

I am still getting the same error

rmboy4oucWjhWs7F8 (P. Nachna…)
2020-09-10 09:06:25.747679+0200  Local[7968:2095790] [objC] didReceiveIncomingPushWithPayload: {
    alert = Test;
    badge = 42;
}
2020-09-10 09:06:25.747874+0200  Local[7968:2095790] [objC] received VoIP message: Test
2020-09-10 09:06:25.748052+0200  Local[7968:2095790] [objC] received data: {
    ConnectionId = Alex123;
    Username = Alex;
}
2020-09-10 09:06:25.748780+0200  Local[7968:2095790] -[__NSDictionaryI dataUsingEncoding:]: unrecognized selector sent to instance 0x2827d5d00
2020-09-10 09:06:25.748990+0200  [7968:2095790] [objC] error: -[__NSDictionaryI dataUsingEncoding:]: unrecognized selector sent to instance 0x2827d5d00
2020-09-10 09:06:25.749409+0200  Local[7968:2095790] Apps receving VoIP pushes must post an incoming call (via CallKit or IncomingCallNotifications) in the same run loop as   pushRegistry:didReceiveIncomingPushWithPayload:forType:[withCompletionHandler:] without delay.
2020-09-10 09:06:25.749612+0200  Local[7968:2095790] *** Assertion failure in -[PKPushRegistry _terminateAppIfThereAreUnhandledVoIPPushes], /Library/Caches/com.apple.xbs/Sources/PushKit/PushKit-37/PKPushRegistry.m:343
2020-09-10 09:06:25.750407+0200  Local[7968:2095790] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP push callback.'
*** First throw call stack:
(0x1a53b9654 0x1a50dbbcc 0x1a52bc6ec 0x1a570216c 0x1b95a9ab8 0x105ffb730 0x10600a488 0x1b95a8a70 0x105ffa338 0x105ffb730 0x106009710 0x1a53376bc 0x1a5332590 0x1a5331ba8 0x1af4a1344 0x1a946d3e4 0x104557a38 0x1a51b98f0)
libc++abi.dylib: terminating with uncaught exception of type NSException

Not sure what i am missing in the whole picture

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

This works fine when app is open.
When the app is closed or in background, notifications are not coming.

Check your project settings in the Apple Developer console. Make sure you are using VOIP push notifications.

Sometimes when app is in background notification is coming, but i am getting this exception in XCode

Exception	NSException *	"Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP push callback."	0x0000000281a58a20

I did mention why this is happening in the wiki section. Reason is because iOS requires us to tell it that there is a call coming in otherwise, the whole operation will be aborted.

I've also mentioned that background notifications won't work for this scenario. If you want to know more, it is right here. I'm sure you have gone through the entire thread there since you also did post there for answers. So, the backend have to be modified to accommodate VOIP push notifications as well. I think there's a type flag that you need to set. I don't remember the property name but it is just basically setting the type of push notification that you want to send out (eg. voip, alert, background, etc). Just check Apple's documentation on that.

To recap, 2 things you need to make sure:

  1. Check settings from Apple Developer console for your project.
  2. Backend services have to be able to push VOIP notifications.

Once you've done with both of them, you should have a working app. I highly suggest you read up on iOS push notifications for VOIP in Apple's documentation if you are still not clear about it.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

I am kinda confused on the part Reason is because iOS requires us to tell it that there is a call coming in otherwise, the whole operation will be aborted. In the code i have shared above (and below), i am triggering the call with cordova.plugins.CordovaCall.receiveCall(data.extra.Username);. Isn't that reporting the call to the OS?

push.on('notification', function(data) {
    Logger.info("notification callback called")
    Logger.info(JSON.stringify(data))
    if (instance.state.isInBackground) {
        instance.state.gotInitiatedInBackground = true
        cordova.plugins.CordovaCall.setVideo(true);
        cordova.plugins.CordovaCall.receiveCall(data.extra.Username);
    }
    // do something based on received data
});

Also regarding the Apple Developer Console, i have a Voip Certificate that i am using with the simplepush.php script. Here is a screenshot of the dev console
https://prnt.sc/ue8eye

What do you mean by Backend services have to be able to push VOIP notifications.?
I am using the script https://github.com/Hitman666/cordova-ios-voip-push/blob/master/pushSendingScript/simplepush.php (a modified version). For the real deal we are probably going to use AWS SNS (which supports Voip Push)
If you mean about using apns-push-type header with the value voip, how would i be able to achieve this with the php script?
Right now the structure i am passing is the following

$payload = json_encode(
	array(
		'aps' => array('alert' => 'badge'),
		'data' => array(
	    'Username' => 'Alex5',
	    'ConnectionId' => 'XXXAlex8'
	    )
	)
);

https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

I am kinda confused on the part Reason is because iOS requires us to tell it that there is a call coming in otherwise, the whole operation will be aborted. In the code i have shared above (and below), i am triggering the call with cordova.plugins.CordovaCall.receiveCall(data.extra.Username);. Isn't that reporting the call to the OS?

push.on('notification', function(data) {
    Logger.info("notification callback called")
    Logger.info(JSON.stringify(data))
    if (instance.state.isInBackground) {
        instance.state.gotInitiatedInBackground = true
        cordova.plugins.CordovaCall.setVideo(true);
        cordova.plugins.CordovaCall.receiveCall(data.extra.Username);
    }
    // do something based on received data
});

No, it doesn't. I think you didn't read thoroughly thru the link I've provided and the wiki section. I did mention why in both of them.

in iOS 13, Cordova WebView won't initialize if the app is not started, upon receiving the VOIP Push Notification. It is started only when the incoming call is reported hence, everything must be handled natively.

I highly suggest you play around with your app's lifecycle to have a better understanding on this.

Also regarding the Apple Developer Console, i have a Voip Certificate that i am using with the simplepush.php script. Here is a screenshot of the dev console
https://prnt.sc/ue8eye

What do you mean by Backend services have to be able to push VOIP notifications.?
I am using the script https://github.com/Hitman666/cordova-ios-voip-push/blob/master/pushSendingScript/simplepush.php (a modified version). For the real deal we are probably going to use AWS SNS (which supports Voip Push)
If you mean about using apns-push-type header with the value voip, how would i be able to achieve this with the php script?
Right now the structure i am passing is the following

$payload = json_encode(
	array(
		'aps' => array('alert' => 'badge'),
		'data' => array(
	    'Username' => 'Alex5',
	    'ConnectionId' => 'XXXAlex8'
	    )
	)
);

https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns

That's exactly what I mean. Your current backend service/script is not able to send out VOIP notifications. All you are doing now is background/normal push notifications. I did mention there's something you need to include. Ah yes, apns-push-type. That's the one. The link that you've shared here already told you on how to do it. Just follow the documentation provided by Apple. It is under the topic, Create and Send a POST Request to APNs and apply it using PHP.

As for your actual environment, I highly suggest you ask Amazon about VOIP push functionality before using their service. AFAIK, there's no support for this on any 3rd party libraries/tools.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

It seems that Amazon AWS has support for this
https://prnt.sc/uee456
I have created a new application there and i can send voip push notifications using the command
aws sns publish --target-arn "arn:aws:sns:us-east-1:{AccountId}:endpoint/APNS_VOIP_SANDBOX/{AppName}/{DeviceTokenId}" --message-structure json --message '{"APNS_VOIP_SANDBOX": "{\"aps\": {\"alert\": \"badge\"}, \"data\": { \"Username\": \"Alex\", \"ConnectionId\": \"Conid\"}, \"priority\": \"high\"}"}' --message-attributes "{\"AWS.SNS.MOBILE.APNS.PRIORITY\":{\"DataType\":\"String\",\"StringValue\":\"10\"}, \"AWS.SNS.MOBILE.APNS.PUSH_TYPE\":{\"DataType\":\"String\",\"StringValue\":\"voip\"} }"

I still dont understanding how reporting the call to the OS can be achieved?
Why the merge is essential? This is essential because in iOS 13, Cordova WebView won't initialize if the app is not started, upon receiving the VOIP Push Notification. It is started only when the incoming call is reported hence, everything must be handled natively.
Does this mean i have to use another plugin or do something else to report the call to the OS?
It would be good if you can point me to an example how i can do that.

Thanks a lot in advance @mattkhaw
Sorry for not being able to understand quickly, i am not a mobile developer :)

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

The plugin will take care of that part when the app is not running. All you have to do is to send a notification to your app. If you said that you can push a VOIP notification, the plugin will react accordingly. If it doesn't, then you are not sending the proper one. It is as simple as that.

Does this mean i have to use another plugin or do something else to report the call to the OS?

If I could find one, I won't need to create myself.

It would be good if you can point me to an example how i can do that.

Wouldn't need an example because it is no different than handling normal push notifications. That is why I've mentioned several times to look at Apple's documentation on this or look at tutorials on how to handle typical push notifications.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

Ok so what you are trying to say is that because i am sending 'wrong' type of push notification, the call is not reported to the OS with your plugin?
I tried 2 different php scripts, houston, and AWS SNS (with the Voip Config specified above) and all of them report this error

2020-09-10 08:26:05.181458+0200  Local[7936:2084907] [objC] didReceiveIncomingPushWithPayload: {
    alert = badge;
}
2020-09-10 08:26:05.181933+0200  Local[7936:2084907] [objC] received VoIP message: badge
2020-09-10 08:26:05.182201+0200  Local[7936:2084907] [objC] received data: {
    ConnectionId = Con123;
    Username = Alex5;
}
2020-09-10 08:26:05.182854+0200  Local[7936:2084907] -[__NSDictionaryI dataUsingEncoding:]: unrecognized selector sent to instance 0x281246a40
2020-09-10 08:26:05.183489+0200  Local[7936:2084907] [objC] error: -[__NSDictionaryI dataUsingEncoding:]: unrecognized selector sent to instance 0x281246a40
2020-09-10 08:26:05.184159+0200  Local[7936:2084907] Apps receving VoIP pushes must post an incoming call (via CallKit or IncomingCallNotifications) in the same run loop as   pushRegistry:didReceiveIncomingPushWithPayload:forType:[withCompletionHandler:] without delay.
2020-09-10 08:26:05.184473+0200  Local[7936:2084907] *** Assertion failure in -[PKPushRegistry _terminateAppIfThereAreUnhandledVoIPPushes], /Library/Caches/com.apple.xbs/Sources/PushKit/PushKit-37/PKPushRegistry.m:343
2020-09-10 08:26:05.186372+0200  Local[7936:2084907] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP push callback.'
*** First throw call stack:
(0x1a53b9654 0x1a50dbbcc 0x1a52bc6ec 0x1a570216c 0x1b95a9ab8 0x103303730 0x103312488 0x1b95a8a70 0x103302338 0x103303730 0x103311710 0x1a53376bc 0x1a5332590 0x1a5331ba8 0x1af4a1344 0x1a946d3e4 0x102a07a38 0x1a51b98f0)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

On this post on SO
https://stackoverflow.com/questions/42004063/voip-push-not-received-in-ios-device/52201060?fbclid=IwAR0gSTI_0QnCU6I8yBoHgcYI-WLXlVHO5CA_IrN5sNPQII5kcvMiyIUTj88
someone is mentioning Your BundleId may be wrong. and Note: Append .voip with your bundleid for sending voip push notification(exmple: bundleid.voip) but i dont think that is a problem for me - because the data is received and all seems ok, except reporting the call to the OS.

As an alternative, is it possible to provide me with a CURL request or something that i can use to call Apple APNS directly ? (although this is done with the php scripts already i assume).

Also in our app we use https://github.com/phonegap/phonegap-plugin-push to interact with FCM and normal push notifications. Do you think this could interfere with your library somehow?

Thanks a lot

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024
2020-09-10 08:26:05.182201+0200  Local[7936:2084907] [objC] received data: {
    ConnectionId = Con123;
    Username = Alex5;
}
2020-09-10 08:26:05.182854+0200  Local[7936:2084907] -[__NSDictionaryI dataUsingEncoding:]: unrecognized selector sent to instance 0x281246a40
2020-09-10 08:26:05.183489+0200  Local[7936:2084907] [objC] error: -[__NSDictionaryI dataUsingEncoding:]: unrecognized selector sent to instance 0x281246a40

There's an error in the plugin which is caused by the payload that you sent in. If you look at the stack trace and trace back to the source code, it is trying to convert to a dictionary with an object, which it will fail since it expects a JSON string.

Also in our app we use https://github.com/phonegap/phonegap-plugin-push to interact with FCM and normal push notifications. Do you think this could interfere with your library somehow?

Not sure since I'm not using that plugin.

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

Like I said before, your payload is incorrect in terms of both structure and data type. Go compare your current payload with the documentation in the README section. As for incorrect data type, refer to my previous post.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

Ok my bad regarding the structure type, i added Caller. Now i need to fix the data type.

CURL
curl -v \
-d '{"aps":{"alert":"Test","badge":42}, "data": {"Caller": {"Username": "Alex", "ConnectionId": "Alex123"}}}' \
-H "apns-topic: com.bundleid.local.voip" \
-H "apns-push-type: voip" \
-H "apns-priority: 10" \
--http2 \
--cert VOIP-local.pem \
https://api.development.push.apple.com/3/device/{deviceToken}

Isn't what i am sending above a JSON string?
How does this work in regard to Objective C parsing?

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

If you look at the log, the function currently sees your payload as an object. It needs to be a string in the format of JSON.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

I guess you are referring to this part only?

2020-09-10 10:32:38.488719+0200 Local[8081:2121679] [objC] received data: {
    Caller =     {
        ConnectionId = Alex123;
        Username = Alex;
    };
}

EDIT: If i try to send the snipper below in the php script

$message = json_encode(
	array(
		'aps' => array('alert' => 'badge'),
		'data' => "Caller : { Username: 'Alex5', ConnectionId: 'Alex123'}"
));

i get

2020-09-10 11:04:02.046453+0200 Local[8081:2121679] [objC] didReceiveIncomingPushWithPayload: {
    alert = badge;
}
2020-09-10 11:04:02.046766+0200 Local[8081:2121679] [objC] received VoIP message: badge
2020-09-10 11:04:02.046925+0200 Local[8081:2121679] [objC] received data: Caller : { Username: 'Alex5', ConnectionId: 'Alex123'}
2020-09-10 11:04:02.047328+0200 Local[8081:2121679] [objC] error: *** -[__NSArray0 objectAtIndex:]: index 1 beyond bounds for empty NSArray
2020-09-10 11:04:02.056159+0200 Local[8081:2121679] info: notification callback called | From: rmboy4oucWjhWs7F8 (P. Nachna…)
2020-09-10 11:04:02.056676+0200 Local[8081:2121679] info: {"extra":"Caller : { Username: 'Alex5', ConnectionId: 'Alex123'}","function":"badge"} | From: rmboy4oucWjhWs7F8 (P. Nachna…)

So it seems i am still missing something
When debugging manually, it seems that json is null - conversion does not pass
https://prnt.sc/uet36j

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

I could not fix the structure on your plugin, therefore i forked it.
Here are the changes i have done
master...AleksandarTokarev:master

Also, here are the 3 ways in which you can invoke VOIP push from your local machine:

  1. AWS SNS
  2. Houston
  3. Direct CURL to Apple APNs

SimplePush Script works as well but i have not included this here

CURL
curl -v -d '{"aps":{"alert":"Test","badge":42}, "data": {"apn_call_name": "Alex1", "apn_call_id": "Alex123"}}' -H "apns-topic: com.bundleid.local.voip" -H "apns-push-type: voip" -H "apns-priority: 10" --http2 --cert VOIP-local.pem https://api.development.push.apple.com/3/device/{deviceId}
AWS SNS SANDBOX
aws sns publish --target-arn "arn:aws:sns:us-east-1:{accountId}:endpoint/APNS_VOIP_SANDBOX/{appName}/{awsGeneratedUrlForToken}" --message-structure json --message '{"APNS_VOIP_SANDBOX": "{\"aps\": {\"alert\": \"badge\"}, \"data\": {\"apn_call_name\": \"Alex\", \"apn_call_id\": \"Alex123\"}, \"priority\": \"high\"}"}' --message-attributes "{\"AWS.SNS.MOBILE.APNS.PRIORITY\":{\"DataType\":\"String\",\"StringValue\":\"10\"}, \"AWS.SNS.MOBILE.APNS.PUSH_TYPE\":{\"DataType\":\"String\",\"StringValue\":\"voip\"} }"
HOUSTON
apn push "<{deviceToken}>" -c VOIP-local.pem -P "{ \"aps\": { \"alert\": \"badge\" }, \"data\": { \"apn_call_name\": \"Alex5\", \"apn_call_id\": \"XXXAex10\"}}"
With this structure the notification is received when app is in background and call starts.
When app is killed, and when i start the app without XCode, the notification is not received. I am not sure if this is related to it being development environment. Will test it on staging environment to see how it behaves with killed app.
Thanks a lot for your help @mattkhaw

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

Like I mentioned previously, all you have to do is to pass in a string, formatted as JSON. This is because of compatibility. If you do that way, you can add as many parameters as you want without modifying the plugin every time a change happens.

I'm aware that there are a few ways to do VOIP push notifications but I always create a custom library to handle this since it will be used in production. It is easier that way because I can debug 2 ends easily. Saves me tons of time instead of jumping through hoops like what you did here.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

@mattkhaw One more question,
It seems your plugin apart from reporting the call invokes the command natively
cordova.plugins.CordovaCall.receiveCall(username);

Why i am asking this?
Because i want to control if the user is in the APP - not to get the Native Calling Screen, and if the user is minimized or in background - to get the Native Calling

Is it possible to achieve this?

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

Consult with your colleague who is doing the backend. There's no way to do it locally. Plus, if you do that, your users will feel awkward having different UIs. It is basic UI/UX design 101.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

We deployed the version to Staging Environment (on TestFlight), VOIP push notifications are coming when app is open and in background, but not when app is killed.
When app is killed the app crashes, here are the logs
https://gist.github.com/AleksandarTokarev/74068feadd728a4bd1c672a024482af4
@mattkhaw any idea why this is happening?

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

No idea. Debug it yourself. It's your app. You should know what's wrong with it.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

This guy on the Apple forums says this crash "0xbaadca11" is happening because a the VOIP push was not reported to Callkit
https://developer.apple.com/forums/thread/124517
The exception code "0xbaadca11" indicates that your app was killled for failing to report a CallKit call in response to a PushKit notificaiton. That should have been clear in the crash log, but this particular requirement is implemented through multiple code paths and it looks like this one isn't as clear as the others. For more details on the new requirement, take a look at:
Strange that this happens only when app is killed, otherwise it works ok

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

Then the only solution is to use Xcode to step through to see what’s wrong. Since you have your modified version of the plugin, check your modifications and see whether it is caused by it.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

The only log i get is the one i posted above.
Since this does not occur when app is started by xcode, i cannot reproduce this locally
Regarding the changes, the only changes i did is with the payload as stated
master...AleksandarTokarev:master
I also tried some other forks but it seems to be same problem

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

Also i am seeing this thread here:
https://stackoverflow.com/questions/61130352/ios-app-crashing-when-recieving-pushkit-voip-notification-after-force-close?fbclid=IwAR2Zz_SVAT0a1m9Dc3gghaHxK_Y2mPE0gkLI-F-g2Em3eLGuPYEjiG0i2PY
Although this guy is not using Cordova, the problem is kinda the same.
I dont see that method "willFinishLaunchingWithOptions" in the code, so i wonder if something is missing
@mattkhaw The only thing that XCode gives me is the log posted above, nothing else (Which says on apple forums that it is callkit related)

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

I managed to fix this by modifying the plugin in the following way:
luisbouca/cordova-plugin-callkit@master...AleksandarTokarev:master
It seems that init() function was not being called when app was KILLED (TERMINATED), so a friend of mine helped me do small refactor and put the init() function code in the plugin initialize. This meant that Pushkit was not initialized (because it was in the init() method)
The init() method is still there, but it is called when that is initialized in Javascript
This is probably related to our Meteor Cordova app and how things are initialized in the app itself.
Now all works fine.
Thanks a lot @mattkhaw

from cordova-plugin-callkit.

neeact avatar neeact commented on July 4, 2024

Hello,
I see that this thread is closed, but we are experiencing the same problem still - I wonder if someone can help?

We have set up our Cordova app to receive VOIP Push notifications.
We have installed all 3 plugins:

  • CordovaCall
  • cordova-plugin-callkit
  • cordova-ios-voip-push

When we send a VOIP Push Notification (i.e. using Houston), using the following CURL command:

apn push "<439c8570d337fa9997cdcd19a016fe83e6867535a87de81739ad89705864995b>" -c voip_services_pem.pem -P "{ "aps": { "alert": {"Caller":{"Username": "Calitos", "ConnectionId": "12121212"}} }, "data": { "apn_call_name": "Zpot", "apn_call_id": "12121212"}}"

we can see in the Xcode log the VOIP notification arriving, with the payload / structure specified in the Callkit plugin:

2020-09-29 14:20:20.574586+0100 Spot[5919:2938863] [objC] didReceiveIncomingPushWithPayload: {
alert = {
Caller = {
ConnectionId = 12121212;
Username = Calitos;
};
};
}
2020-09-29 14:20:20.574801+0100 Spot[5919:2938863] [objC] received VoIP msg: {
Caller = {
ConnectionId = 12121212;
Username = Calitos;
};
}

But the problem is that Cordova Call is not being called (I mean, nothing happens).
Can you please point me in the right direction?
What could we be missing here?

Thank you for your help masters!

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

Hello @neeact ,
You dont need to install 3 plugins, you only need this one (or the one that i forked to work with MeteorJS - but it would work in any case)
If you want to use my fork for IOS, you can add it like this (referencing latest commit).

cordova-plugin-callkit@https://github.com/AleksandarTokarev/cordova-plugin-callkit.git#4ffd7063a567e05d77da20f7f6a20128f81ee109

It seems you are missing the payload structure, you need it "data" : "Caller" : {...}
Here is how it looks:
With houston, you can use

apn push "<{deviceToken}>" -c VOIP-local.pem -P "{ \"aps\": { \"alert\": \"badge\" }, \"data\": {  \"Caller\": { \"Username\": \"Alex5\", \"ConnectionId\": \"XXXAex10\"}}}"

Our server is NodeJS backend based and we are using AWS SNS to send VOIP pushes, so here is the code we have for sending there

let voip_protocol_value = `{"aps" : { "alert": "New Incoming Call" }, "data" : { "Caller": { "Username" : "${caller}", "ConnectionId": "${Random.id()}"}}}`
                let payload = {}
                payload['APNS_VOIP'] = voip_protocol_value
                let params = {
                    'Message': JSON.stringify(payload),
                    'MessageAttributes': {
                        'AWS.SNS.MOBILE.APNS.PRIORITY': {
                            'DataType': 'String',
                            'StringValue': '10'
                        },
                        'AWS.SNS.MOBILE.APNS.PUSH_TYPE': {
                            'DataType': 'String',
                            'StringValue': 'voip'
                        },
                        'AWS.SNS.MOBILE.APNS_VOIP.TTL': {
                            'DataType': 'String',
                            'StringValue': '0'
                        },
                    },
                    'MessageStructure': 'json',
                    'TargetArn':endpointArn
                }

await sns.publish(params).promise()

If you want to test it locally, replace APNS_VOIP with APNS_VOIP_SANDBOX in both places

Let me know if u have any other questions or need help

from cordova-plugin-callkit.

neeact avatar neeact commented on July 4, 2024

Thank you Aleksandar,

I tried your Houston code, but the CordovaCall was not fired and I got this in the log:

2020-09-29 16:53:34.560590+0100 Spot[6013:2985285] [objC] didReceiveIncomingPushWithPayload: {
alert = badge;
}
2020-09-29 16:53:34.560777+0100 Spot[6013:2985285] [objC] received VoIP message: badge
2020-09-29 16:53:34.560931+0100 Spot[6013:2985285] [objC] received data: {
Caller = {
ConnectionId = XXXAex10;
Username = Alex5;
};
}
2020-09-29 16:53:34.561090+0100 Spot[6013:2985285] -[__NSSingleEntryDictionaryI dataUsingEncoding:]: unrecognized selector sent to instance 0x2836ec300
2020-09-29 16:53:34.562015+0100 Spot[6013:2985285] [objC] error: -[__NSSingleEntryDictionaryI dataUsingEncoding:]: unrecognized selector sent to instance 0x2836ec300

Should I remove the CordovaCall and iOS VOIP Push plugins?
Txs!

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

Yes remove them and leave only 1 plugin (my fork or Matthew's - but i had problem with the payload structure with his original plugin)
Also the received Data part is good, that is what we need

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

@neeact You can't use CordovaCall and cordova-ios-voip-push plugins independently, you need to use the combined plugin to achieve the desired effect. The sole reason why this exists is to make both plugins be able to talk to each other. Just remove both of them unless you want to use it separately and reduce code bulk. Otherwise, the combined one works fine.

from cordova-plugin-callkit.

neeact avatar neeact commented on July 4, 2024

Ok - I see - but we still need to retrieve the device token when it register for push notifications - is this also available in this combined plugin? If not, we will still need to use the cordova-ios-voip-push to get the device token with push.on('registration', function(data){ ... });

Regarding the problem we are having using the cordova-plugin-callkit plugin probably this is caused by the fact that using Houston or CURL to make the VOIP push call we are not able to send the payload as an actual JSON object - I guess we should try to send the voip push call using Node to see if this solves the problem.

from cordova-plugin-callkit.

mattkhaw avatar mattkhaw commented on July 4, 2024

Like I mentioned previously, all you have to do is to pass in a string, formatted as JSON. This is because of compatibility. If you do that way, you can add as many parameters as you want without modifying the plugin every time a change happens.

I did mention it here, if you did read all the way through that is.

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

@neeact With this plugin, you can use the code from cordova-ios-voip-push plugin (basically it is merged here), to listen for on registration event. With this, you can save the token in the database for lets say User A. After that, UserB wants to call UserA, checks the database if the VOIP token is in the database for that user, if it is, you can call directly Apple APN or use AWS SNS for that (my code above - have in mind this is another layer of complexity that you have to manage).
Also i was having problems with the JSON payload so that's why i ended up modifying the plugin in the first place

from cordova-plugin-callkit.

neeact avatar neeact commented on July 4, 2024

Yes - I read your comments and documentation thoroughly - but when we send the voip push with the string (fortades as a standard json), we receive an exception:

push being sent:
apn push "<439c8570d337fa9997cdcd19a016fe83e6867535a87de81739ad89705864995b>" -c voip_services_pem.pem -P '{ "aps": "{Caller:{Username: Calitos, ConnectionId: 12121212}}"}' or

apn push "<439c8570d337fa9997cdcd19a016fe83e6867535a87de81739ad89705864995b>" -c voip_services_pem.pem -P '{ "aps": "{Caller:{Username: "Calitos", ConnectionId: "12121212"}}"}'

Xcode log:
2020-09-30 09:32:13.901225+0100 Spot[6186:3112457] [objC] didReceiveIncomingPushWithPayload: {Caller:{Username: Calitos, ConnectionId: 12121212}}
2020-09-30 09:32:13.901592+0100 Spot[6186:3112457] -[__NSCFString objectForKeyedSubscript:]: unrecognized selector sent to instance 0x280d9c870
2020-09-30 09:32:13.901961+0100 Spot[6186:3112457] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKeyedSubscript:]: unrecognized selector sent to instance 0x280d9c870'
*** First throw call stack:
(0x1bdac5654 0x1bd7e7bcc 0x1bd9c9dd8 0x1bdac97f8 0x1bdacb71c 0x104bece5c 0x1d1cbaa3c 0x10620e338 0x10620f730 0x10621d710 0x1bda436bc 0x1bda3e590 0x1bda3dba8 0x1c7bb4344 0x1c1b793e4 0x104bb4c2c 0x1bd8c58f0)
libc++abi.dylib: terminating with uncaught exception of type NSException

When we analyse the log we can see that the push is received with the correct payload: {Caller:{Username: Calitos, ConnectionId: 12121212}} but it looks that when iOS tries to launch the call interface it throws an exception.

Do you know what is happening?
Can you point me to the right direction please?

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

@neeact Try it with this payload
apn push "<{deviceToken}>" -c VOIP-local.pem -P "{ \"aps\": { \"alert\": \"badge\" }, \"data\": { \"Caller\": { \"Username\": \"Alex5\", \"ConnectionId\": \"XXXAex10\"}}}"
With this payload make sure you are using my fork, because i could not get it to work with the original plugin structure

The exception you are throwing above is being thrown because you are not sending the correct payload structure.

from cordova-plugin-callkit.

neeact avatar neeact commented on July 4, 2024

@AleksandarTokarev with your Fork and the push you suggest, the call interface is called!

However, if the App is in background or unloaded, the call is not triggered :(
Do you know why?
Isn't it supposed the VOIP push to work in background / unloaded app as well?

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

It should work in background/unloaded app as well. Are you using Cordova with MeteorJS or Ionic?
With my fork, this works for us in background/killed as well - We are using MeteorJS (dont think it should matter).
Make sure you delete/reinstall the app before that (in case if it failed several times, it wont trigger it)

from cordova-plugin-callkit.

neeact avatar neeact commented on July 4, 2024

Ok - it's working in the background as well.
I had to uninstall the application and install it again in order for the voip push notifications work in the background (because when installing the App I had to authorize to receive notifications).

For the sake of sanity - after all this discussion, I leave below my conclusions:

1 - Use the cordova-plugin-callkit from AleksandarTokarev fork (@ https://github.com/AleksandarTokarev/cordova-plugin-callkit). The initial plugin from mattkhaw didn't work in our case...

2 - send a push notification with the following structure (using Houston as example): apn push "<{!device_token}>" -c voip_service_certificate_file.pem -P "{ "aps": { "alert": "Incoming call" }, "data": { "Caller": { "Username": "Alex5", "ConnectionId": "XXXAex10"}}}"

3 - if needed, uninstall your application and install it again to allow notifications in the background / app killed modes.

Thank you so much for your help @AleksandarTokarev !!!

from cordova-plugin-callkit.

AleksandarTokarev avatar AleksandarTokarev commented on July 4, 2024

@neeact No problem, i spend quite some time to figure it out myself. Glad i helped :)

from cordova-plugin-callkit.

rgustavsson avatar rgustavsson commented on July 4, 2024

Well done on all your efforts guys.

Just want to mention that I also had some issue with this plugin. I know that I'm sending VOIP notifications but things were not working out when the app was killed or in the background (xcode saying "Killing app because it never posted an incoming call..").

I also switched to use the cordova-plugin-callkit from AleksandarTokarev fork (@ https://github.com/AleksandarTokarev/cordova-plugin-callkit) and now things are working as expected.

from cordova-plugin-callkit.

Related Issues (15)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.