Skip to content

Handling the missed call notification on iOS when the call has been ended from caller side . #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Kushagra-Esmagico opened this issue Apr 15, 2025 · 10 comments

Comments

@Kushagra-Esmagico
Copy link

In our current call flow, we’ve identified an edge case affecting the callee's experience when there is no internet connectivity (e.g., Airplane Mode):

The callee is offline due to Airplane Mode.

The caller initiates a call.

After ringing for 30 seconds without a response, the call is terminated due to timeout.

The callee regains internet access (turns off Airplane Mode).

The VoIP notification is delivered to the callee device.

The app incorrectly triggers the CallKit UI, assuming an active incoming call.

If the callee tries to answer, the attempt fails as the call is no longer active.

✅ Expected Behavior
Upon receiving the VoIP notification after the call has already ended, the app should not present the CallKit UI. Instead, it should display a missed call notification, aligning with user expectations and preventing confusion.

This logic is already implemented for Android using the sentTime field from the notification and comparing it to the current time:

DateTime nowTime = DateTime.now();
Duration? difference = nowTime.difference(message.sentTime!);

if (difference.inSeconds > StringConstant.callMissedTimeout) {
NotificationService.showMissedCallNotification(message);
return;
}
🚫 Issue on iOS
Currently, iOS VoIP (PushKit) notifications do not include a sent_time field or any metadata indicating when the notification was originally triggered. As a result, the iOS app cannot determine whether the incoming call is still valid or already expired.

🔧 Proposed Solution
To bring parity with Android and handle stale calls more gracefully, we propose adding a new field to the VoIP push payload:

Field Name: sent_time

Type: UTC ISO 8601 formatted timestamp (e.g., "2025-04-15T08:35:00Z")

Placement: Inside the metadata dictionary of the VoIP push payload.

{
"aps": {
"content-available": 1
},
"metadata": {
"call_id": "sdjdjjdjd-5120-46d1-adjhsadjdh-ds",
"caller_name": "1933333333",
"caller_number": "1933333333",
"sent_time": "2025-04-15T08:35:00Z", // <-- NEW FIELD
...
}
}

✅ Expected Outcome
With the sent_time field available:

The iOS app can calculate the delay between sent_time and the current time.

If the delay exceeds a defined threshold (e.g., 35 seconds), the app will skip CallKit presentation and instead show a missed call notification.

This improves reliability, avoids false-positive call screens, and ensures consistent UX across platforms.

Please let us know if this change can be incorporated on the server side or VoIP notification sender logic. We’re happy to collaborate on implementation details if needed.

@Oliver-Zimmerman
Copy link
Collaborator

Hi @Kushagra-Esmagico

As discussed on the call. We are looking into this issue internally. We will keep you in the loop with our findings.

This will be linked to the issue reported here:
#126

@Kushagra-Esmagico
Copy link
Author

@Oliver-Zimmerman is there any findings for this issue , or any chance for new release to resolve this from SDK side?

@Oliver-Zimmerman
Copy link
Collaborator

@Kushagra-Esmagico

@isaacakakpo1 will update you here, he works more directly on the native iOS stuff than I and has been looking into this.

@isaacakakpo1
Copy link
Contributor

isaacakakpo1 commented May 13, 2025

Hey @Kushagra-Esmagico , We suggest the following approach for handling stale incoming VoIP notifications on iOS in the mean time. while we work on making the change to the Push MetaData:

Using Custom Headers : You can include the sent_time as a custom header when you make a call. For example :

  void call(String destination) {
    final String sentTime =
        DateTime.now().toIso8601String(); // "2025-05-13T14:05:00.000Z"
    _currentCall = _telnyxClient.newInvite(
      _localName,
      _localNumber,
      destination,
      'Fake State',
      customHeaders: {'X-Sent-Time': sentTime},
    );
    observeCurrentCall();
  }

// Received Like 

{... dialogParams: {custom_headers: [{name: X-Sent-Time, value: 2025-05-13T14:05:00.000Z}, {name: X-RTC-CALLID, value: fb2395bf-5e7b-40af-bc1d-f67368c854b6}, voice_sdk_id: VSDK1Ch8dUTpaPQzIoR-JQc2ZZsiEOgfMPQ}

This way you can use a custom date format of your choice. However because push notifications can delay few or more seconds. I will suggest the window to consider a push notification stale to be at least 45 secs.

We have an internal ticket to include a sent_time param to easily handle the case. Apple does have some requirements for showing callkit notifications. More on that here : https://developer.apple.com/documentation/pushkit/responding-to-voip-notifications-from-pushkit#Respond-to-Call-Hang-Ups-and-Failure

@Kushagra-Esmagico
Copy link
Author

Hey @isaacakakpo1 , We are not testing within the Telnyx Sytem only, So inbound calls may be triggered from any other provider. What you have suggested will work only in case of calls from Telnyx to Telnyx.

@Oliver-Zimmerman
Copy link
Collaborator

Sorry @Kushagra-Esmagico, I was not aware that you did not get a reply.

sent_time is being added as a param and should be out soon. It is currently in dev undergoing testing. I will update you here.

@farhat-ha
Copy link

@Kushagra-Esmagico @Oliver-Zimmerman
sent_time is now included in the push notification metadata

@Kushagra-Esmagico
Copy link
Author

@farhat-ha Thank you for the update. I will be testing with above changes, and update here.

@Kushagra-Esmagico
Copy link
Author

@farhat-ha @Oliver-Zimmerman @isaacakakpo1
I have tested with the additional change in notification data. It's working fine. We can close this ticket.
Thank you for your support.

@Oliver-Zimmerman
Copy link
Collaborator

Thanks @Kushagra-Esmagico

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants