Est-il possible de savoir si l'application a été lancée / ouverte à partir d'une notification push?
Je suppose que l'événement de lancement peut être capturé ici:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions != nil) {
// Launched from push notification
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
}
}
Cependant, comment puis-je détecter qu'elle a été ouverte à partir d'une notification push lorsque l'application était en arrière-plan?
Réponses:
Voir ce code:
pareil que
la source
en retard mais peut-être utile
Lorsque l'application n'est pas en cours d'exécution
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
est appelé ..
où vous devez vérifier la notification push
la source
Le problème que nous avons rencontré était de mettre à jour correctement la vue après le lancement de l'application. Il y a ici des séquences compliquées de méthodes de cycle de vie qui prêtent à confusion.
Méthodes du cycle de vie
Nos tests pour iOS 10 ont révélé les séquences suivantes de méthodes de cycle de vie pour les différents cas:
Le problème
Ok, alors maintenant nous devons:
Le problème est que la mise à jour de la vue doit avoir lieu lorsque l'application devient réellement active, ce qui est la même méthode de cycle de vie dans tous les cas.
Esquisse de notre solution
Voici les principaux composants de notre solution:
notificationUserInfo
variable d'instance sur AppDelegate.notificationUserInfo = nil
à la foisapplicationWillEnterForeground
etdidFinishLaunchingWithOptions
.notificationUserInfo = userInfo
endidReceiveRemoteNotification:inactive
applicationDidBecomeActive
toujours appeler une méthode personnaliséeopenViewFromNotification
et passerself.notificationUserInfo
. Si la valeurself.notificationUserInfo
est nulle, retournez tôt, sinon ouvrez la vue en fonction de l'état de notification trouvé dansself.notificationUserInfo
.Explication
Lors de l'ouverture à partir d'un push
didFinishLaunchingWithOptions
ouapplicationWillEnterForeground
est toujours appelé immédiatement avantdidReceiveRemoteNotification:inactive
, nous avons donc d'abord réinitialisé notificationUserInfo dans ces méthodes afin qu'il n'y ait pas d'état périmé. Ensuite, sididReceiveRemoteNotification:inactive
est appelé, nous savons que nous ouvrons à partir d'un push, donc nous définissonsself.notificationUserInfo
ce qui est ensuite capté parapplicationDidBecomeActive
pour transférer l'utilisateur vers la bonne vue.Il y a un dernier cas qui est si l'utilisateur a l'application ouverte dans le commutateur d'application (c'est-à-dire en appuyant deux fois sur le bouton d'accueil pendant que l'application est au premier plan), puis reçoit une notification push. Dans ce cas, seul
didReceiveRemoteNotification:inactive
est appelé, et ni WillEnterForeground ni didFinishLaunching ne sont appelés, vous avez donc besoin d'un état spécial pour gérer ce cas.J'espère que cela t'aides.
la source
receive
méthodes lorsque l'état de l'application est actif ou que l'application reprend. Cela pourrait entraîner des problèmes de modification des VC lorsque l'application est toujours inactive. Votre solution est superbe, jusqu'à ce qu'Apple modifie à nouveau le cycle de vie.applicationWillResignActive
est appelé, puis leapplicationDidBecomeActive
. Ainsi, après l'applicationWillResignActive
appel, ne sauvegardez pas la notification reçue jusqu'à ce queapplicationDidEnterBackground
ouapplicationDidBecomeActive
soit appelé.C'est un article bien usé ... mais il manque encore une solution réelle au problème (comme cela est souligné dans les différents commentaires).
La raison peut être vue dans le flux d'appels lorsqu'une notification arrive,
application:didReceiveRemoteNotification...
est appelé lorsque la notification est reçue ET à nouveau lorsque la notification est tapée par l'utilisateur. Pour cette raison, vous ne pouvez pas dire en regardant simplement
UIApplicationState
si l'utilisateur l'a tapé.De plus, vous n'avez plus besoin de gérer la situation d'un `` démarrage à froid '' de l'application
application:didFinishLaunchingWithOptions...
commeapplication:didReceiveRemoteNotification...
on l'appelle à nouveau après le lancement dans iOS 9+ (peut-être aussi 8).Alors, comment pouvez-vous savoir si l'utilisateur tap a commencé la chaîne d'événements? Ma solution consiste à marquer l'heure à laquelle l'application commence à sortir de l'arrière-plan ou à démarrer à froid, puis à enregistrer cette heure
application:didReceiveRemoteNotification...
. S'il est inférieur à 0,1 s, vous pouvez être à peu près sûr que le robinet a déclenché le démarrage.Swift 2.x
Swift 3
J'ai testé cela pour les deux cas (application en arrière-plan, application non exécutée) sur iOS 9+ et cela fonctionne comme un charme. 0,1 s est également assez prudent, la valeur réelle est de ~ 0,002 s, donc 0,01 convient également.
la source
UNNotificationCenter
API, en particulier les méthodes UNNotificationCenterDelegate. Ces API appellent lauserNotificationCenter(UNUserNotificationCenter, didReceive: UNNotificationResponse, withCompletionHandler: @escaping () -> Void)
méthode func uniquement lorsque l'utilisateur a réellement tapé sur la notification.applicationWillEnterForeground
appel, par conséquent, la solution ne parvient pas à détecter le robinet.UNUserNotificationCenter.current().delegate
dansapplication:didFinishLaunchingWithOptions
, l'application appellerauserNotificationCenter(didReceive response)
après le robinet dans le cas que vous avez décritLorsque l'application est terminée et que l'utilisateur appuie sur la notification push
Lorsque l'application est en arrière-plan et que l'utilisateur appuie sur la notification push
En fonction de votre application, il peut également vous envoyer un push silencieux à l'
content-available
intérieuraps
, alors soyez conscient de cela également :) Voir https://stackoverflow.com/a/33778990/1418457la source
Swift 2.0 pour l'état `` non exécuté '' (notification locale et distante)
la source
En
application:didReceiveRemoteNotification:
vérifier si vous avez reçu la notification lorsque votre application est au premier plan ou arrière - plan.S'il a été reçu en arrière-plan, lancez l'application à partir de la notification.
la source
Pour rapide:
la source
Oui, vous pouvez détecter par cette méthode dans appDelegate :
Pour la notification locale:
la source
si quelqu'un veut la réponse dans Swift 3
la source
Publier ceci pour les utilisateurs Xamarin.
La clé pour détecter si l'application a été lancée via une notification push est la
AppDelegate.FinishedLaunching(UIApplication app, NSDictionary options)
méthode et le dictionnaire d'options transmis.Le dictionnaire des options aura cette clé si elle est une notification locale:
UIApplication.LaunchOptionsLocalNotificationKey
.S'il s'agit d'une notification à distance, ce sera le cas
UIApplication.LaunchOptionsRemoteNotificationKey
.Lorsque la clé est
LaunchOptionsLocalNotificationKey
, l'objet est de typeUILocalNotification
. Vous pouvez ensuite consulter la notification et déterminer de quelle notification il s'agit.Astuce de pro:
UILocalNotification
n'a pas d'identifiant dedans, de la même manièreUNNotificationRequest
. Placez une clé de dictionnaire dans UserInfo contenant un requestId afin que, lors du test deUILocalNotification
, vous ayez un requestId spécifique disponible sur lequel baser une logique.J'ai constaté que même sur les appareils iOS 10+, lors de la création de notifications de localisation à l'aide du
UNUserNotificationCenter
'sAddNotificationRequest
&UNMutableNotificationContent
, lorsque l'application n'est pas en cours d'exécution (je l'ai tuée), et qu'elle est lancée en appuyant sur la notification dans le centre de notification, que le dictionnaire contient toujours l'UILocalNotificaiton
objet.Cela signifie que mon code qui vérifie le lancement basé sur les notifications fonctionnera sur les appareils iOS8 et iOS 10+
la source
Directement à partir de la documentation pour
Si l'application est en cours d'exécution et reçoit une notification à distance, l'application appelle cette méthode pour traiter la notification.
Votre implémentation de cette méthode doit utiliser la notification pour prendre une mesure appropriée.
Et un peu plus tard
Si l'application n'est pas en cours d'exécution lorsqu'une notification push arrive, la méthode lance l'application et fournit les informations appropriées dans le dictionnaire des options de lancement.
L'application n'appelle pas cette méthode pour gérer cette notification push.
Au lieu de cela, votre implémentation du
ou
La méthode doit obtenir les données de charge utile de notification push et répondre de manière appropriée.
la source
Je vais commencer par un graphique d'état que j'ai créé pour ma propre utilisation afin de le visualiser plus précisément et de prendre en compte tous les autres états: https://docs.google.com/spreadsheets/d/e/2PACX-1vSdKOgo_F1TZwGJBAED4C_7cml0bEATqeL3P9UKpBwASl0bEATqeL3P9UKpBwASlT6ZkU3htgbwASlT6ZkU3htgdlzlzlzlg ? gid = 0 & single = true
En utilisant ce graphique, nous pouvons voir ce qui est réellement nécessaire pour développer un système de gestion des notifications robuste qui fonctionne dans presque tous les cas d'utilisation possibles.
Solution complète ↓
Remarque: une réponse similaire est suggérée dans les commentaires sur la réponse d'Eric, cependant, la feuille d'état aide à trouver tous les scénarios possibles, comme je l'ai fait dans mon application.
Veuillez trouver le code complet ci-dessous et commenter ci-dessous si un cas spécifique n'est pas traité:
AppDelegate
NotificationUtils : C'est ici que vous pouvez écrire tout votre code pour naviguer vers différentes parties de l'application, gérer les bases de données (CoreData / Realm) et faire toutes les autres tâches à effectuer lorsqu'une notification est reçue.
la source
la source
Il n'y a qu'un seul moyen fiable, et cela ne fonctionne que pour iOS 10+ :
Utilisation de la méthode de
UNUserNotificationCenter
mise en œuvreUNUserNotificationCenterDelegate
:la source
Vous pouvez utiliser:
pour gérer les notifications push à distance.
Consultez ici la documentation
la source
Je n'ai pas encore essayé mais peut-être pourriez-vous vous envoyer une notification? http://nshipster.com/nsnotification-and-nsnotificationcenter/
la source
la source
Le problème avec cette question est que «l'ouverture» de l'application n'est pas bien définie. Une application est soit lancée à froid à partir d'un état non en cours d'exécution, soit réactivée à partir d'un état inactif (par exemple, pour y revenir à partir d'une autre application). Voici ma solution pour distinguer tous ces états possibles:
Et
MXDefaults
c'est juste un petit emballage pourNSUserDefaults
.la source
Pour
swift
la source
Xcode 10 Swift 4.2
la source
Pour iOS 10+, vous pouvez utiliser cette méthode pour savoir quand votre notification est cliquée, quel que soit l'état de l'application.
la source
La réponse de M.Othman est correcte pour les applications qui ne contiennent pas de délégué de scène Pour les applications de délégué de scène Cela a fonctionné pour moi sur iOS 13
Voici le code pour qui doit être écrit dans la scène de connexion
Code pour que le délégué d'application prenne en charge les versions antérieures didFinishLaunchingWithOptions
la source
Pour les utilisateurs Swift:
Si vous souhaitez lancer une page différente à l'ouverture de push ou quelque chose comme ça, vous devez l'enregistrer
didFinishLaunchingWithOptions
comme:la source
DANS SWIFT:
J'exécute des notifications push (avec récupération en arrière-plan). Lorsque mon application est en arrière-plan et que je reçois une notification push, j'ai trouvé que didReceiveRemoteNotification dans appDelegate serait appelé deux fois; une fois lorsque la notification est reçue et une autre lorsque l'utilisateur clique sur l'alerte de notification.
Pour détecter si une alerte de notification a été cliquée, vérifiez simplement si la valeur brute applicationState == 1 dans didReceiveRemoteNotification dans appDelegate.
J'espère que ça aide.
la source
Lorsque l'application est en arrière-plan en tant que shanegao, vous pouvez utiliser
Mais si vous souhaitez lancer l'application et lorsque l'application est fermée et que vous souhaitez déboguer votre application, vous pouvez aller dans Modifier le schéma et dans le menu de gauche, sélectionnez Exécuter , puis au lancement, sélectionnez Attendre le lancement de l'exécutable , puis le lancement de l'application lorsque vous cliquez sur la notification push
Modifier le schéma> Exécuter> Attendre le lancement de l'exécutable
la source