web-dev-qa-db-fra.com

application: didReceiveRemoteNotification: fetchCompletionHandler Not Called

Il semble que la fonction application:didReceiveRemoteNotification:fetchCompletionHandler ne soit pas appelée lorsque l'application a été forcée de quitter. J'avais l'impression que la fonction serait invoquée quel que soit l'état de l'application, mais il semble qu'elle ne soit appelée que si l'application est déjà en cours d'exécution en arrière-plan. Existe-t-il un moyen de réactiver une application en arrière-plan si elle ne fonctionne pas déjà avec le nouveau mode d'arrière-plan de notification à distance iOS 7?

22
Wes Cossick

application:didReceiveRemoteNotification:fetchCompletionHandler: est appelé même si l'application est suspendue, inexistante, en arrière-plan ou active. Il convient également de noter que la méthode est iOS 7 uniquement. Voici la Documentation Apple .

TOUTEFOIS, si l'application a été fermée de force (c'est-à-dire en tuant avec le commutateur d'application), l'application sera lancée non. (voir SO réponse ) EDIT: J'ai vérifié cela à nouveau sur iOS 7.1 pour voir s'ils corrigeaient ce problème, mais cela ne changerait pas est tué manuellement, l'application ne sera pas réveillée et application:didReceiveRemoteNotification:fetchCompletionHandler: ne sera pas appelé

Lors de la réception du Push, l'application n'est réveillée que "si nécessaire" pour appeler la méthode application:didReceiveRemoteNotification:fetchCompletionHandler: (c'est-à-dire que vous devez définir l'indicateur "content-available" dans le contenu de la notification Push. Voir SO réponse ). La méthode s'appellera encore si l'utilisateur ouvre ensuite l'application en appuyant sur la notification.

EDIT: n'a pas vérifié cela sur iOS 8. A quelqu'un d'autre?

50
nvrtd frst
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary
*)launchOptions {

    //Remote Notification Info
    NSDictionary * remoteNotifiInfo = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];

    //Accept Push notification when app is not open
    if (remoteNotifiInfo) {
       [self application:application didReceiveRemoteNotification: remoteNotifiInfo];
    }

    return YES;
}
23
kid

Lorsque votre application a été forcée, cette méthode n'est pas appelée. Comme d'habitude, (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions est appelé.

Si l'application a été ouverte en appuyant sur "Ouvrir" dans une notification, la notification se trouve à l'intérieur de launchOptions.

Obtenez le dictionnaire de notifications Push comme ceci:

NSDictionary * pushNotificationUserInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

if (pushNotificationUserInfo)
{
  // call your handler here
}
3
scrrr

L'application devrait être lancée même si elle n'est pas en cours d'exécution. La documentation Apple indique:

Lorsque cette valeur est présente et qu'une notification Push arrive sur un périphérique, le système envoie la notification à votre application ( en la lançant si nécessaire ) et lui donne quelques instants pour traiter> la notification avant d'afficher quoi que ce soit à l'utilisateur . (Guide de programmation de l'application iOS)

Lorsqu'une notification Push arrive, le système affiche la notification à l'utilisateur et à lance l'application en arrière-plan (si nécessaire) pour qu'il puisse appeler cette méthode . (Référence du protocole UIApplicationDelegate)

Contrairement à l'application: didReceiveRemoteNotification: méthode, qui n'est appelée que lorsque votre application est en cours d'exécution, le système appelle cette méthode, quel que soit l'état de votre application. Si votre application est suspendue ou en cours d'exécution , le système active ou lance votre application et met dans l'état d'exécution en arrière-plan avant d'appeler la méthode . (Référence du protocole UIApplicationDelegate)

Cependant, lorsque vous testez avec "content-available": 1 demande que l'application ne soit jamais lancée lorsqu'elle n'est pas en cours d'exécution. Lorsque l'application est suspendue, cela fonctionne.

As-tu trouvé une solution Wes?

3
Emiel

Comme indiqué par Apple, la nouvelle API multitâche (extraction et notification à distance) fonctionnera uniquement lorsque l'application sera dans l'état suspendu/arrière-plan/avant-plan.

  • Dans l'état background/foreground, alors application:didReceiveRemoteNotification:fetchCompletionHandler sera déclenché.

  • Dans l'état Suspended, alors -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions sera déclenché.

  • Dans l'état Not Running (votre cas), application:didReceiveRemoteNotification:fetchCompletionHandler n'est jamais déclenché. 

Veuillez vous référer à Documentation Apple pour plus d'informations sur les états des applications.

2
Nandha

Pour qui le souci dans Swift 2.0 j'ai résolu mon problème comme ceci est pour le fond

if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {

    pushNotificationAction(remoteNotification as [NSObject : AnyObject])
}
1
Luai Kalkatawi

Si vous forcez la fermeture d'une application à partir du sélecteur d'applications, elle ne sera réveillée en arrière-plan (par aucun moyen) avant la prochaine fois qu'elle sera lancée. Lorsque vous forcez la fermeture d'une application, vous dites effectivement au système d'exploitation que vous ne voulez pas qu'elle s'exécute du tout, même si un événement en arrière-plan l'aurait normalement réveillé.

Cela vaut la peine d'être surveillé pendant les tests, car vous pourriez avoir à forcer la fermeture de l'application pour vérifier qu'elle est lancée via la notification Push lorsque l'application n'est pas en cours d'exécution. En fait, votre usage de la force sera la raison pourquoi il ne sera pas lancé.

1
Dave Addey

J'ai récemment rencontré le même problème et j'ai découvert qu'Apple avait mis à jour sa documentation et écrit:

Cependant, le système ne lance pas automatiquement votre application si l'utilisateur l'a forcée à la quitter. Dans ce cas, l'utilisateur doit relancer votre application ou redémarrer l'appareil avant que le système ne tente de relancer automatiquement votre application.

application (_: didReceiveRemoteNotification: fetchCompletionHandler :)

Donc, je suppose qu'il n'y a aucun moyen de faire quoi que ce soit lorsque l'application est tuée de force par la force?

0
HunTer DRF