iOS push notification: comment détecter si l'Utilisateur a tapé sur notification lorsque l'application est en arrière-plan?

il y a beaucoup de fils stackoverflow concernant ce sujet, mais je n'ai toujours pas trouvé une bonne solution.

Si l'application n'est pas dans le fond, je peux vérifier launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] dans application:didFinishLaunchingWithOptions: appel pour voir si elle est ouverte à partir d'une notification.

Si l'application est en arrière-plan, tous les postes suggère l'utilisation de application:didReceiveRemoteNotification: et de vérifier l'état de l'application. Mais comme j'ai expérimenté (et aussi comme le nom de cette API suggère), cette méthode obtient appelé lorsque la notification est reçue, au lieu de les exploiter.

donc, le problème est, si l'application est lancée et puis backgrounded, et vous savez qu'une notification est reçue de application:didReceiveNotification ( application:didFinishLaunchWithOptions: ne se déclenchera pas à ce point), comment savez-vous si l'Utilisateur a repris l'application en tapant la notification ou en tapant simplement l'icône de l'application? Parce que si l'utilisateur a appuyé sur l'notification, l'attente est d'ouvrir la page mentionnée dans la notification. Sinon, il ne devrait pas.

je pourrais utiliser handleActionWithIdentifier pour les notifications d'actions personnalisées, mais cela ne se déclenche que lorsqu'un bouton d'action personnalisé est activé, pas lorsque l'utilisateur tape sur le corps principal de la notification.

Merci.

EDIT:

après avoir lu une réponse ci-dessous, j'ai pensé que de cette façon je peux clarifier ma question:

Comment distinguer ces deux scénarios:

(Un) 1.App passe à l'arrière-plan; 2.notification reçue; 3. l'utilisateur tape sur la notification; 4. l'application entre en ligne de compte

(B) 1.app va à fond; 2.notification reçue; 3. l'utilisateur ignore la notification et tape sur l'icône de l'application plus tard; 4. l'application entre en ligne de compte

depuis application:didReceiveRemoteNotification: est déclenché dans les deux cas à l'étape 2.

Ou, application:didReceiveRemoteNotification: déclenché à l'étape 3 pour (A) seulement, mais j'ai configuré mon application de mal, donc je suis le voir à l'étape 2?

83
demandé sur Hamid sh 2015-08-18 03:46:46

8 réponses

OK j'ai finalement compris.

dans l'onglet target settings pace Capabilities, si vous cochez" Remote Notifications", application:didReceiveRemoteNotification: sera déclenché dès que la notification arrive (tant que l'application est en arrière-plan), et dans ce cas, il n'y a aucun moyen de dire si l'utilisateur va taper sur la notification.

si vous décochez cette case, application:didReceiveRemoteNotification: ne sera déclenché que lorsque vous cliquerez sur la notification.

c'est un peu étrange que de cocher cette case va changer le comportement d'une des méthodes de l'app delegate. Il serait plus agréable si cette case est cochée, Apple utilise deux méthodes de délégué différentes pour la réception de la notification et le robinet de notification. Je pense que la plupart des développeurs veulent toujours savoir si une notification est exploité ou non.

espérons que cela sera utile pour tous ceux qui se trouvent dans cette question. Apple n'a pas non plus documenté clairement ici ça m'a pris du temps.

enter image description here

78
répondu Bao Lei 2015-08-18 18:02:33

j'ai cherché la même chose que vous et j'ai trouvé une solution qui n'exige pas de notification à distance à cocher.

Pour vérifier si l'utilisateur a tapé, ou l'application est en arrière-plan ou est active, vous n'avez qu'à vérifier l'état de l'application dans

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{

    if(application.applicationState == UIApplicationStateActive) {

        //app is currently active, can update badges count here

    }else if(application.applicationState == UIApplicationStateBackground){

        //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here

    }else if(application.applicationState == UIApplicationStateInactive){

        //app is transitioning from background to foreground (user taps notification), do what you need when user taps here

    }

Pour plus d'informations, consultez:

UIKit Cadre De Référence > UIApplication Classe De Référence > UIApplicationState

56
répondu Dennism 2016-02-18 08:05:51

selon iOS / XCode: comment savoir que l'application a été lancée avec un clic sur la notification ou sur l'icône de l'application springboard? vous devez vérifier l'état de la demande dans la notification didreceivelocal comme ceci:

if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive)
{
    // user has tapped notification
}
else
{
    // user opened app from app icon
}

bien que cela n'ait pas tout à fait de sens pour moi, cela semble fonctionner.

18
répondu Werner Kratochwil 2017-05-23 12:18:16

si quelqu'un le veut dans swift 3.0

switch application.applicationState {
    case .active:
        //app is currently active, can update badges count here
        break
    case .inactive:
        //app is transitioning from background to foreground (user taps notification), do what you need when user taps here
        break
    case .background:
        //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
        break
    default:
        break
    }
12
répondu Hamid sh 2016-12-21 09:02:31

Si vous avez d'arrière-plan "Modes" > "notifications à Distance" checked == OUI, appuyez sur la notification de l'événement arrivera dans:

-(void)userNotificationCenter:(UNUserNotificationCenter *)center **didReceiveNotificationResponse**:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler.

ça m'a aidé. S'il vous plaît profiter :)

3
répondu Aleks Osipov 2017-09-15 08:25:20

j'ai rencontré ce problème, aussi - mais sur iOS 11 avec le nouveau cadre UserNotifications .

ici pour moi, c'est comme ça:

  • Nouveau Lancement: application:didFinishLaunchingWithOptions:
  • reçu en premier plan: application:didReceiveRemoteNotification:fetchCompletionHandler:
  • reçu en arrière-plan: userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
3
répondu pre 2018-04-03 11:02:09

dans mon cas, le mode arrière-plan éteint n'a fait aucune différence. Cependant, lorsque l'application a été suspendue et que l'Utilisateur a tapé la notification, je pouvais gérer le cas dans cette méthode de rappel:

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {

}
0
répondu DoruChidean 2018-06-19 12:39:11

vous pouvez configurer la charge utile de votre notification push pour appeler la méthode application:didReceiveRemoteNotification:fetchCompletionHandler: de l'app delegate lorsque l'app est en arrière-plan. Vous pouvez mettre un certain drapeau ici de sorte que lorsque l'utilisateur lance votre application la prochaine fois, vous pouvez effectuer votre opération.

de la documentation d'apple, vous devez utiliser ces méthodes pour télécharger de nouveaux contenus associés à la notification push. Pour que cela fonctionne, vous devez activer la notification à distance à partir des modes D'arrière-plan et de votre push la charge utile de notification doit contenir la clé content-available dont la valeur est fixée à 1. Pour plus d'informations, veuillez consulter utiliser les Notifications Push pour lancer une section de téléchargement à partir de apple doc ici .

une autre façon est de faire compter les badges dans la charge utile de notification push. Alors, la prochaine fois que votre application démarre, vous pouvez vérifier l'application compteur. Si son supérieur à zéro, effectuez votre opération et zéro/effacer le compteur de serveur aussi.

Espérons que cela vous aide.

-6
répondu Bhushan 2015-08-18 09:54:36