[iOS 13 Beta 2] PushKit notifications do not get delivered while the app is in the background

Our messaging application with VoIP feature build with Xcode 11 beta 2 and running iOS 13 beta 2 stoped receiving notifications over PushKit while the app is in the background or not runnig. At the same time notifications get delivered fine when the app is in the foreground.


The issue with notifications not delivered to a backgrounded app appears to be the system issue as they get delivered to the phone but not passed to the app. The fact that a notifction gets delivered to the phone can be conformed with apsd process logs which appears as follows in our case


: Received message for enabled topic 'com.MyAppName.voip' onInterface: NonCellular with payload '{
    aps =     {
         ...
}' with priority (null) for device token: NO


This is a recent regression in the beta 2, since we could not reproduce it with beta 1.

Replies

We have a similar problem with notifications not being received when the app is suspended or in the background.

The Remote Notifications background mode is on, and all worked w/o issues in previous iOS-es...

Getting this as well.

On iOS 13.0 and later, incoming Voice over IP calls must be reported when they are received and before the didReceiceIncomingPush() method finishes execution, using the CallKit framework, or the system will terminate your app.


Repeatedly failing to report calls may prevent your app from receiving any more incoming call notifications.


Basically, you can no longer use VoIP pushes for non VoIP messaging, and will need to use regular push notifications for those.


This was announced during the WWDC session "Advances in App Background Execution" https://developer.apple.com/videos/play/wwdc2019/707/

In the WWDC session, the example code has this:



...

if let handle = payload.dictionaryPayload["handle"] as? String

{

let callUpdate = CXCallUpdate()

callUpdate.remoteHandle = CXHandle(type: .phoneNumber, value: handle)

let callUUID = UUID()

provider.reportNewIncomingCall(with: callUUID, update: callUpdate) { _ in

completion()

}

}

...


So the voIP push payload must now contain some identifying handle? And within reportNewIncommingCall is an associated made between that handle and the callUUID value?


What is the behavior of the OS if some random handle value is passed such as:


let callUpdate = CXCallUpdate()

callUpdate.remoteHandle = CXHandle(type: .phoneNumber, value: "Just basically some random string")

let callUUID = UUID()

provider.reportNewIncomingCall(with: callUUID, update: callUpdate) { _ in

completion()

}

>> will need to use regular push notifications for those.


With < iOS 13 (and it seems it will also be the case for iOS 13), silent push notifications are highly highly unreliable, for example

- if the app was terminated by the user they are not delivered at all

- if the battery power is <= 40%, the OS receives the push but often delays delivering it to the app for a few minutes

- if the batter pwer is >= 20, the OS receives the push but decides not to forward it to the app at all

- many other criteria affect whether the OS actually delivers the push to the app or not


Do regular, silent, notifications have any increased opportunity for actually getting delivered to the app with iOS 13?


Thank you

Thanks for the pointers to WWDC talk. I'm seeing the following error when trying to present ringing notifications when receiving Voip Push:


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.

Could you help clarify what "IncomingCallNotifications" stands for here?

@Gualtier MaldeWhat if the incoming Voip call/push should be blocked? If the app could just ignore the push then the call is effectively blocked, but as its a mandatory requirement to call reportNewIncomingCall() then how can the call be blocked?

If the incoming number has been blocked using the CallKit extension, and if the blocked number is passed to reportNewIncomingCall() then the OS still displays the call screen.

So its impossible for an app to implement Voip call blocking with iOS 13 because the call screen is always going to be displayed?

Hi Gaultier


I presume that this change is to try to prevent abuse of VoIP Pushes for non VoIP apps but I really don't understand the logic of insisting on reporting the call before didReceiceIncomingPush() method finishes execution?


Is there some way to avoid this? Maybe to allow a few seconds after receiving the VoIP push within which to start the call.


Our VoIP App needs to open a connection to the VoIP server and get some information about the call before actually having enough information to place the call via Callkit. This will no longer be possible and so our already deployed telephony servers will need to be changed significantly to have this new requirement of sending all Caller information in the actual VoIP Push.


I am sure that this new requirement will have very severe consequences for most real VoIP Apps especially as it will be required in the very near future for iOS13. I would respectfully suggest that Apple reconsider this change or at least give a reasonable amount of time to adapt to this new requirement, Introduce in iOS14 or something??


I also agree with mungbeans points about blocked calls and the unreliable nature of regular push notifications. VoIP Apps need to have critical timely updates about "missed calls" and "voicemails" when such features as Do No Disturb or Call Forwarding to Voicemail or to other users are used within the VoIP Server. The quality of VoIP Apps will be affected.

antonf_ua, when did your app stop receiving VoIP PNs? As soon as you installed iOS 13 beta 2, or after a while using the app?

I would also like to ask antonf_ua (and rmendes22) if you were using


the Development Push Server (api.development.push.apple.com Port 443) running from Xcode connected to an iPhone

or

standalone iphone with the real server (api.push.apple.com Port 443)


I suppose my question is will the real server stop sending the pushes or just the development server at this stage?


I don't seem to get any pushes from (api.development.push.apple.com Port 443) arriving at the phone but do seem to get pushes from the real server (api.push.apple.com Port 443)


I'm not sure if I did get pushes from (api.development.push.apple.com Port 443) and then they stopped.


Its all really confusing

In our case we are using the production server and VoIP pushes are received and delivered correctly to the app.

I also tested WhatsApp and they are also receiving VoIP pushes correctly.


But this is using an app built with Xcode 10 (iOS 12). We cannot yet build with Xcode 11 due to an external dependency that hasn't been updated yet, we should be able to check this in the next days.


That's why I asked antonf_ua because we are not sure if VoIP pushes are not delivered for any app on iOS 13 after some bad uses or just for apps built with the iOS 13 SDK.

Hi rmendes22


Just to be clear with what I'm seeing....


I have not changed anything with my code to meet this new "incoming Voice over IP calls must be reported when they are received and before the didReceiceIncomingPush() method finishes execution"


If I use an ipa that was built with Xcode 10 for iOS12 and install that on an iOS13Beta3 iPhone then it seems to always get the Pushes from the Production server and rings for the incoming call (With callkit).. However when I answer the call I get a blank screen on the iPhone. I dont see any phone (Either native screen for a locked iPhone or my Apps oncall screen if the phoen had been unlocked when the call arrived)


If I run with my iPhone with iOS13Beta3 connected to XCode 11 Beta3 then pushes should come from the "development server"(api.development.push.apple.com Port 443). I am not seeing those pushes arriving. I dont think I ever did but I'm not 100% sure?


Tomorrow I will test some more.

I managed to make some more tests and this seems to only occur in apps built with the iOS 13 SDK (Xcode 11 beta):


- App built with Xcode 10, run on iOS 13 device: all good, VoIP pushes are received and app stays running in background;

- App built with Xcode 11, run on iOS 13 device: after first VoIP push without reporting incoming call app is immediately killed and no more VoIP pushes are delivered;


If confirmed this will at least give us some extra time to adapt until linking with iOS 13 SDK is mandatory for App Store submission. But I'm still at a lost on how we can achieve the requirement given that we use SIP and need to register and receive an invite to an incoming call after a push is received and check if the call should be allowed or not, all that while having to immediately report the call to CallKit.


I've contacted Apple via email getting a generic and useless "check App Store Guidelines" answer, I cannot submit a TSI for beta software and no definitive answer has been given here on the forums.


I would very much like to know how are the "big players" like WhatsApp, Telegram, Messenger, etc going to deal with this change...

Hi rmendes22


1. Xcode 10 Vs Xcode13Beta3

=======================

From my testing today I have come to the same conclusions as you have ...


It seems that if you build with XCode10 then that build seems to work ok with Both Development and Production Push servers. The App is not "killed". I only see Apps built with XCode11Beta running on iOS13Beta3 devices getting "killed"


As you say if Apple can formally confirm that then at least we know that we can build our Apps with XCode 10 until XCode 11 becomes mandatory. Therefore when iOS13 is formally released in Sep our Apps will still work for our customers etc. So we have a reasonable time hopefully to adapt to the new Requirement with Callkit.


2. The requested new behaviour

========================

How we are meant to offer the call to Callkit before


(void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload

forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion


returns is a huge problem for us too.


There is a completion handler here which I don't really understand the purpose of. It would have made sense to me that you could call the completion handler once you had offered the call to callkit. In that way you have time to register to the SIP server and get it's INVITE.


I tried to do this today but it did not work. However if that was the case then it would meet Apple's goal of stopping abuse of the VoIP Pushes for non VoIP purposes and also keep normal SIP architecture viable.


Maybe Apple can consider this approach or maybe I am misunderstanding the purpose of the completion handler.


3. Other Issues

===========

We also have 3 other VoIP issues with iOS13Beta3 even when build with Xcode10

1) When answer a call (When iPhone is unlocked) we get a blank screen. We don't see the in-call screen. I also see this with Viber and WhatsApp

2) When answer a call from Locked screen we see the native in-call screen screen but get an failure with Audio. I also see this with Viber and WhatsApp

3) The call always seems to be offered with the normal ringtone even though we asked callkit to use a custom one.


Do you see these issues too?

Hi Gualtier MaldeGualtier,


Could you please take a look at the following link? https://forums.developer.apple.com/thread/117939


iOS CallKit is a great feature in iOS.

As I can see the new VoIP push limitation in iOS 13 will mess up many companies' VoIP call services. And it will push their customers' to use Android phones instead of iPhones...
May I know if Apple give these 3rd party VoIP companies time to adjust their services? And if the current limitation is reasonable enough?


Our company also tried to file a TSI, but it's rejected due to iOS13 is in beta status.


Is there any best practice for VoIP services on iOS13?

  • If we have to report incoming call on every VoIP push, how do we notify the app to stop ringing? Usually, we use another VoIP push to tell the app
  • If there is a local setting to mute incoming calls, what should we do after we receive the VoIP push?


Thanks a lot!

Albert Gu