¿Es posible saber si la aplicación se inició / abrió desde una notificación push?
Supongo que el evento de lanzamiento se puede ver aquí:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions != nil) {
// Launched from push notification
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
}
}
Sin embargo, ¿cómo puedo detectar que se abrió desde una notificación push cuando la aplicación estaba en segundo plano?
Respuestas:
Ver este código:
igual que
fuente
tarde pero tal vez útil
Cuando la aplicación no se está ejecutando
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
se llama ..
donde necesita verificar la notificación push
fuente
El problema que tuvimos fue la actualización correcta de la vista después de iniciar la aplicación. Aquí hay secuencias complicadas de métodos de ciclo de vida que se vuelven confusas.
Métodos de ciclo de vida
Nuestras pruebas para iOS 10 revelaron las siguientes secuencias de métodos de ciclo de vida para varios casos:
El problema
Ok, ahora necesitamos:
Lo complicado es que la actualización de la vista tiene que suceder cuando la aplicación realmente se activa, que es el mismo método de ciclo de vida en todos los casos.
Bosquejo de nuestra solución.
Estos son los principales componentes de nuestra solución:
notificationUserInfo
variable de instancia en AppDelegate.notificationUserInfo = nil
en ambosapplicationWillEnterForeground
ydidFinishLaunchingWithOptions
.notificationUserInfo = userInfo
endidReceiveRemoteNotification:inactive
applicationDidBecomeActive
siempre llame a un método personalizadoopenViewFromNotification
y paseself.notificationUserInfo
. Siself.notificationUserInfo
es nulo, regrese temprano, de lo contrario abra la vista en función del estado de notificación que se encuentra enself.notificationUserInfo
.Explicación
Cuando se abre desde una inserción
didFinishLaunchingWithOptions
oapplicationWillEnterForeground
siempre se llama inmediatamente antesdidReceiveRemoteNotification:inactive
, por lo que primero restablece NoticeIserInfo en estos métodos para que no haya un estado obsoleto. Luego, sididReceiveRemoteNotification:inactive
se llama, sabemos que estamos abriendo desde un empuje, por lo que configuramos elself.notificationUserInfo
que luego se recogeapplicationDidBecomeActive
para reenviar al usuario a la vista correcta.Hay un caso final que es si el usuario tiene la aplicación abierta dentro del selector de aplicaciones (es decir, tocando dos veces el botón de inicio mientras la aplicación está en primer plano) y luego recibe una notificación push. En este caso solo
didReceiveRemoteNotification:inactive
se llama, y ni WillEnterForeground niFinishLaunching son llamados, por lo que necesita un estado especial para manejar ese caso.Espero que esto ayude.
fuente
receive
métodos cuando el estado de la aplicación está activo o la aplicación se reanuda. Eso podría generar problemas al cambiar los VC cuando la aplicación aún está inactiva. Su solución se ve genial, hasta que Apple cambie el ciclo de vida nuevamente.applicationWillResignActive
se llama al y luego alapplicationDidBecomeActive
. Por lo tanto, después de laapplicationWillResignActive
llamada, no guarde la notificación recibida hasta que se llame aapplicationDidEnterBackground
oapplicationDidBecomeActive
.Esta es una publicación muy desgastada ... pero todavía le falta una solución real al problema (como se señala en los diversos comentarios).
La razón se puede ver en el flujo de llamadas cuando llega una notificación,
application:didReceiveRemoteNotification...
recibe una llamada cuando se recibe la notificación Y nuevamente cuando el usuario toca la notificación. Debido a esto, no se puede saber con solo mirar
UIApplicationState
si el usuario lo tocó.Además, ya no necesita manejar la situación de un "arranque en frío" de la aplicación
application:didFinishLaunchingWithOptions...
comoapplication:didReceiveRemoteNotification...
se llama nuevamente después del lanzamiento en iOS 9+ (quizás 8 también).Entonces, ¿cómo puede saber si el toque del usuario inició la cadena de eventos? Mi solución es marcar la hora a la que la aplicación comienza a salir del fondo o iniciar en frío y luego verificar esa hora
application:didReceiveRemoteNotification...
. Si es inferior a 0.1s, puede estar seguro de que el toque activó el inicio.Swift 2.x
Swift 3
He probado esto para ambos casos (aplicación en segundo plano, aplicación no se ejecuta) en iOS 9+ y funciona de maravilla. 0.1s también es bastante conservador, el valor real es ~ 0.002s, por lo que 0.01 también está bien.
fuente
UNNotificationCenter
API, específicamente los métodos UNNotificationCenterDelegate. EsosuserNotificationCenter(UNUserNotificationCenter, didReceive: UNNotificationResponse, withCompletionHandler: @escaping () -> Void)
métodos de función de llamada API solo cuando el usuario ha hecho tapping en la notificación.applicationWillEnterForeground
llamada, como resultado, la solución no puede detectar el toque.UNUserNotificationCenter.current().delegate
enapplication:didFinishLaunchingWithOptions
, la aplicación llamaráuserNotificationCenter(didReceive response)
después del toque en el caso que describióCuando finaliza la aplicación y el usuario toca la notificación push
Cuando la aplicación está en segundo plano y el usuario toca la notificación push
Dependiendo de su aplicación, también puede enviarle un empuje silencioso con el
content-available
interioraps
, así que tenga en cuenta esto también :) Consulte https://stackoverflow.com/a/33778990/1418457fuente
Swift 2.0 para estado 'No en ejecución' (Notificación local y remota)
fuente
En
application:didReceiveRemoteNotification:
comprobación de si ha recibido la notificación cuando su aplicación está en el primer o segundo plano.Si se recibió en segundo plano, inicie la aplicación desde la notificación.
fuente
Para rápido:
fuente
Sí, puede detectar por este método en appDelegate :
Para notificaciones locales:
fuente
si alguien quiere la respuesta en Swift 3
fuente
Publicar esto para los usuarios de Xamarin.
La clave para detectar si la aplicación se inició mediante una notificación push es el
AppDelegate.FinishedLaunching(UIApplication app, NSDictionary options)
método y el diccionario de opciones que se pasa.El diccionario opciones tendrá esta clave en ella si se trata de una notificación locales:
UIApplication.LaunchOptionsLocalNotificationKey
.Si es una notificación remota, lo será
UIApplication.LaunchOptionsRemoteNotificationKey
.Cuando la clave es
LaunchOptionsLocalNotificationKey
, el objeto es de tipoUILocalNotification
. Luego puede ver la notificación y determinar qué notificación específica es.Pro-tip:
UILocalNotification
no tiene un identificador, de la misma maneraUNNotificationRequest
. Ponga una clave de diccionario en la información de usuario que contenga un requestId para que al probarloUILocalNotification
, tenga un requestId específico disponible para basar algo de lógica.Descubrí que incluso en dispositivos iOS 10+ que al crear notificaciones de ubicación usando
UNUserNotificationCenter
'sAddNotificationRequest
&UNMutableNotificationContent
, que cuando la aplicación no se está ejecutando (la eliminé), y se inicia tocando la notificación en el centro de notificaciones, que el diccionario todavía contiene ElUILocalNotificaiton
objeto.Esto significa que mi código que verifica el lanzamiento basado en notificaciones funcionará en dispositivos iOS8 e iOS 10+
fuente
Directamente de la documentación para
Si la aplicación se está ejecutando y recibe una notificación remota, la aplicación llama a este método para procesar la notificación.
Su implementación de este método debe usar la notificación para tomar un curso de acción apropiado.
Y un poco mas tarde
Si la aplicación no se está ejecutando cuando llega una notificación push, el método inicia la aplicación y proporciona la información adecuada en el diccionario de opciones de inicio.
La aplicación no llama a este método para manejar esa notificación push.
En cambio, su implementación de la
o
El método necesita obtener los datos de la carga útil de notificaciones push y responder adecuadamente.
fuente
Voy a empezar con una tabla de estado que he creado para mi propio uso para visualizar con mayor precisión y considerar todos los otros estados: https://docs.google.com/spreadsheets/d/e/2PACX-1vSdKOgo_F1TZwGJBAED4C_7cml0bEATqeL3P9UKpBwASlT6ZkU3iLdZnOZoevkMzOeng7gs31IFhD-L/pubhtml ? gid = 0 & single = true
Usando este cuadro, podemos ver lo que realmente se requiere para desarrollar un sistema robusto de manejo de notificaciones que funcione en casi todos los casos de uso posibles.
Solución completa ↓
Nota: Se sugiere una respuesta similar en los comentarios sobre la respuesta de Eric, sin embargo, la hoja de estado ayuda a encontrar todos los escenarios posibles como lo hice en mi aplicación.
Encuentre el código completo a continuación y comente a continuación si no se maneja un caso específico:
AppDelegate
NotificationUtils : aquí es donde puede escribir todo su código para navegar a diferentes partes de la aplicación, manejar bases de datos (CoreData / Realm) y hacer todo lo demás que debe hacerse cuando se recibe una notificación.
fuente
fuente
Solo hay una forma confiable y funciona solo para iOS 10+ :
Usando el método de
UNUserNotificationCenter
implementaciónUNUserNotificationCenterDelegate
:fuente
Puedes usar:
para manejar las notificaciones push remotas.
Consulta aquí la documentación
fuente
Todavía no lo he probado, pero ¿podrías enviarte una notificación? http://nshipster.com/nsnotification-and-nsnotificationcenter/
fuente
fuente
El problema con esta pregunta es que "abrir" la aplicación no está bien definida. Una aplicación se inicia en frío desde un estado que no se está ejecutando o se reactiva desde un estado inactivo (por ejemplo, al volver a cambiarla desde otra aplicación). Aquí está mi solución para distinguir todos estos posibles estados:
Y
MXDefaults
es solo un pequeño envoltorio paraNSUserDefaults
.fuente
por
swift
fuente
Xcode 10 Swift 4.2
fuente
Para iOS 10+, puede usar este método para saber cuándo se hace clic en su notificación, independientemente del estado de la aplicación.
fuente
La respuesta de M.Othman es correcta para aplicaciones que no contienen delegado de escena Para aplicaciones de delegado de escena Esto funcionó para mí en iOS 13
Aquí está el código para el que se debe escribir se conectará escena
El código para el delegado de la aplicación para admitir versiones anteriores didFinishLaunchingWithOptions
fuente
Para usuarios rápidos:
Si desea iniciar una página diferente al abrir desde push o algo así, debe registrarla
didFinishLaunchingWithOptions
como:fuente
EN SWIFT:
Estoy ejecutando notificaciones push (con recuperación de fondo). Cuando mi aplicación está en segundo plano y recibo una notificación push, descubrí que didReceiveRemoteNotification en appDelegate se llamaría dos veces; una vez cuando se recibe la notificación y otra cuando el usuario hace clic en la alerta de notificación.
Para detectar si se hizo clic en la alerta de notificación, solo verifique si applicationState raw value == 1 inside didReceiveRemoteNotification en appDelegate.
Espero que esto ayude.
fuente
Cuando la aplicación está en segundo plano como shanegao , puedes usar
Pero si desea iniciar la aplicación y cuando la aplicación está cerrada y desea depurar su aplicación, puede ir a Editar esquema y en el menú de la izquierda seleccionar Ejecutar y luego en Ejecutar seleccionar Esperar a que se ejecute el ejecutable y luego iniciar la aplicación cuando haga clic en notificación push
Editar esquema> Ejecutar> Esperar a que se ejecute el ejecutable
fuente