web-dev-qa-db-fra.com

iOS 13 Killing app car elle n'a jamais publié d'appel entrant sur le système après avoir reçu un rappel PushKit VoIP

Après la mise à niveau vers iOS beta 13, j'ai remarqué une chose désagréable: mon application se bloque parfois lors des push VoIP entrants.

Dans le rapport de crash, je vois ce qui suit:

iOS 13 Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP callback 

Fatal Exception: NSInternalInconsistencyException
0  CoreFoundation                 0x1af21b9f0 __exceptionPreprocess
1  libobjc.A.dylib                0x1af7284fc objc_exception_throw
2  CoreFoundation                 0x1af11efec + 
 [_CFXNotificationTokenRegistration keyCallbacks]
3  Foundation                     0x1aeda1330 -[NSAssertionHandler 
 handleFailureInMethod:object:file:lineNumber:description:]
4  PushKit                        0x19caa6b54 -[PKPushRegistry 
 _terminateAppIfThereAreUnhandledVoIPPushes]
5  libdispatch.dylib              0x1afa441ec _dispatch_client_callout
6  libdispatch.dylib              0x1af9f6c6c 
_dispatch_lane_barrier_sync_invoke_and_complete
7  PushKit                        0x19caa5b74 __73-[PKPushRegistry 
 voipPayloadReceived:mustPostCall:withCompletionHandler:]_block_invoke
8  libdispatch.dylib              0x1afa43678 
 _dispatch_call_block_and_release
9  libdispatch.dylib              0x1afa441ec 
  _dispatch_client_callout

10 libdispatch.dylib              0x1af9f61f8 
_dispatch_main_queue_callback_4CF$VARIANT$mp
11 CoreFoundation                 0x1af1992a0 
CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE
12 CoreFoundation                 0x1af1942a8 __CFRunLoopRun
13 CoreFoundation                 0x1af1937ac CFRunLoopRunSpecific
14 GraphicsServices               0x1ae395180 GSEventRunModal
15 UIKitCore                      0x1b6e60244 UIApplicationMain
16 VOIPProject                    0x1009822d8 main + 25 
(AppDelegate.Swift:25)
17 libdyld.dylib                  0x1af6e9e7c start

Je ne comprends pas comment résoudre le problème. Suis-je obligé de publier l'écran des appels entrants de CallKit chaque fois que je reçois un push VoIP? Cela semble fou parce que je vérifie si la notification est valide avant d'afficher l'écran avec l'appel entrant. Quelqu'un peut-il expliquer ce que je dois faire?

16
Marina

Sur ce thread de Apple forums, quelqu'un de Apple staff a expliqué ceci:

Sur iOS 13.0 et versions ultérieures, les appels Voix sur IP entrants doivent être signalés lorsqu'ils sont reçus et avant que la méthode didReceiceIncomingPush () ne termine son exécution, en utilisant le framework CallKit, sinon le système mettra fin à votre application.

L'omission répétée de signaler les appels peut empêcher votre application de recevoir d'autres notifications d'appels entrants.

Fondamentalement, vous ne pouvez plus utiliser les push VoIP pour les messages non VoIP et devrez utiliser des notifications Push régulières pour celles-ci.

Cela a été annoncé lors de la session WWDC "Advances in App Background Execution" https://developer.Apple.com/videos/play/wwdc2019/707/


J'ai cherché des réponses sur la façon d'adapter une application à ce changement, et ce que j'ai pu recueillir est le suivant:

Push VoIP

Lorsque votre application reçoit ce type de Push, elle devra signaler un nouvel appel entrant à l'aide de CallKit. Par conséquent, ce type de Push sera exclusif pour les appels utilisant CallKit.

Il est recommandé de définir le apns-expiration De la notification sur 0, afin de ne pas recevoir de Push et être obligé de présenter un écran d'appel pour un appel qui a déjà expiré.

Notifications push

Les notifications Push régulières sont une autre option. Si votre serveur dispose de toutes les informations dont vous avez besoin pour rédiger le texte de notification, vous pouvez envoyer des notifications qui n'exécuteront même pas votre application en arrière-plan. Si vous devez modifier le contenu de la notification avant de la présenter à l'utilisateur, vous pouvez utiliser une extension d'application Notification Service, et si vous avez besoin que votre application soit réveillée et exécute quelque chose en arrière-plan, vous pouvez envoyer des notifications Push silencieuses.

Extension d'application du service de notification

Pour l'utiliser, vous devez définir le mutable-content De votre notification sur 1. De cette façon, votre extension recevra la notification avant qu'elle ne soit présentée à l'utilisateur, vous permettant de modifier son contenu, avec un délai de 30 secondes.

Les inconvénients sont que votre application restera en arrière-plan, seule votre extension sera autorisée à s'exécuter. Cela peut signifier que vous devrez partager des informations et du code entre votre application et l'extension, soit en utilisant les valeurs par défaut de l'utilisateur, le trousseau ou en partageant l'intégralité de votre base de données (ce qui pourrait ne pas être une tâche simple si votre application n'est pas préparée pour cela). .

Notifications push silencieuses

Pour envoyer des notifications Push silencieuses, vous devez définir le content-available De votre notification sur 1 et le supprimer alert, badge et sound. Cette notification réveillera votre application en arrière-plan et appellera le délégué de votre application didReceiveRemoteNotification.

Les inconvénients sont assez ennuyeux pour cette option:

  • Vous n'aurez que 30 secondes pour courir.
  • Ces notifications doivent avoir un apns-priority De 5, ce qui peut entraîner leur regroupement et leur remise en rafales, voire leur limitation ou leur non remise.
  • Si l'utilisateur force la fermeture de l'application, il ignorera complètement toutes les notifications silencieuses jusqu'à ce que l'utilisateur ouvre à nouveau l'application.
29
pepsy