¿IOS lanzará mi aplicación en segundo plano si fue forzada a salir por el usuario?

219

Estoy activando una búsqueda de fondo usando la content-availablebandera en una notificación push. Tengo el fetchy remote-notification UIBackgroundModeshabilitado.

Aquí está la implementación que estoy usando en mi AppDelegate.m:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"Remote Notification Recieved");
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody =  @"Looks like i got a notification - fetch thingy";
    [application presentLocalNotificationNow:notification];
    completionHandler(UIBackgroundFetchResultNewData);

}

Cuando la aplicación se ejecuta en segundo plano, funciona bien. (Se recibe la notificación y la aplicación activó la notificación local "Parece que recibí una notificación", como debería hacer el código anterior).

Sin embargo, cuando la aplicación no se está ejecutando y se recibe una notificación push con el content-availableindicador, la aplicación no se inicia y didRecieveRemoteNotificationnunca se llama al método delegado.

El video WWDC Qué hay de nuevo con la multitarea (# 204 de WWDC 2013) muestra esto:ingrese la descripción de la imagen aquí

Dice que la aplicación se "inicia en segundo plano" cuando se recibe una notificación push con la content-availablebandera.

¿Por qué mi aplicación no se inicia en segundo plano?

Entonces la verdadera pregunta es:

¿IOS realizará tareas en segundo plano después de que el usuario haya forzado el cierre de la aplicación?

Papá Noel
fuente
¿Cómo verifica si la aplicación se inicia en segundo plano?
runmad
1
@runmad Registro un montón de basura- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Santa Claus
¿Cómo lo estás registrando, solo NSLog? Tendrá que establecer el Inicio en manual en la configuración del esquema de su aplicación (ver respuesta)
runmad
@runmad ver comentario en respuesta
Santa Claus
@HaimBenchimol Djd, ¿recibe una respuesta a su informe de error? No he podido presentar mi propio informe de error.
Papá Noel

Respuestas:

215

ACTUALIZACIÓN2:

Usted puede lograr esto mediante el nuevo marco PushKit, introducido en iOS 8. Aunque PushKit se utiliza para VoIP. Por lo tanto, su uso debe estar relacionado con VoIP; de lo contrario, existe el riesgo de rechazo de la aplicación. (Ver esta respuesta ).


UDPDATE1:

La documentación ha sido aclarada para iOS8 . La documentación se puede leer aquí . Aquí hay un extracto relevante:

Use este método para procesar las notificaciones remotas entrantes para su aplicación. A diferencia del application:didReceiveRemoteNotification:método, que se llama solo cuando su aplicación se ejecuta en primer plano, el sistema llama a este método cuando su aplicación se ejecuta en primer plano o en segundo plano. Además, si habilitó el modo de fondo de notificaciones remotas, el sistema inicia su aplicación (o la activa desde el estado suspendido) y la pone en estado de fondo cuando llega una notificación push. Sin embargo, el sistema no inicia automáticamente su aplicación si el usuario la ha forzado a salir. En esa situación, el usuario debe reiniciar su aplicación o reiniciar el dispositivo antes de que el sistema intente iniciar su aplicación automáticamente nuevamente.


Aunque esto no fue aclarado por el video de WWDC, una búsqueda rápida en los foros de desarrolladores reveló esto:

https://devforums.apple.com/message/873265#873265 (se requiere inicio de sesión)

También tenga en cuenta que si elimina su aplicación desde el conmutador de aplicaciones (es decir, deslizar hacia arriba para eliminar la aplicación), el sistema operativo nunca volverá a ejecutar la aplicación, independientemente de la notificación push o la búsqueda de fondo. En este caso, el usuario debe reiniciar manualmente la aplicación una vez y, a partir de ese momento, se invocarán las actividades en segundo plano. - pmarcos

Esa publicación fue de un empleado de Apple, así que creo que puedo confiar en que esta información es correcta.

Por lo tanto, parece que cuando la aplicación se elimina del conmutador de aplicaciones (deslizando hacia arriba), la aplicación nunca se iniciará, incluso para las recuperaciones de fondo programadas.

Papá Noel
fuente
2
Para mí, agregar la acción en "didFinishLaunchingWithOptions" cuando las opciones de inicio no son nulas hizo el trabajo. Tengo el mismo método aquí que en "didReciveRemoteNotification"
harsh.prasad
@ harsh.prasad eso es interesante. El problema era que la aplicación no se inicia cuando la aplicación ha sido eliminada del conmutador de aplicaciones.
Papá Noel
3
La aplicación no necesita mostrarse en el conmutador de aplicaciones si se recibe un envío silencioso. Se podría iniciar en segundo plano sin agregarlo al conmutador de aplicaciones, y se le permitirá ejecutar y "hacer lo suyo" y luego salir. Las aplicaciones que permanecen activas durante demasiado tiempo se eliminarán de la misma manera que ya.
MindJuice
1
@chrizstone La solución es que este es el comportamiento previsto, y no puede hacer nada al respecto.
Santa Claus
1
@JPK Uh, las notificaciones push no se ven afectadas. Solo está haciendo tareas en segundo plano que no funcionarán después de que se haya forzado el cierre.
Papá Noel
70

Puede cambiar la configuración de inicio de su objetivo en "Administrar esquema" a Wait for <app>.app to be launched manually, lo que le permite depurar estableciendo un punto de interrupción application: didReceiveRemoteNotification: fetchCompletionHandler:y enviando la notificación de inserción para activar el inicio en segundo plano.

No estoy seguro de que resuelva el problema, pero puede ayudarlo con la depuración por ahora.

captura de pantalla

runmad
fuente
así que esto ayudó, pero el problema aún existe
Santa Claus el
Extraño. ¿Supongo que has verificado más de dos veces que todos los flashes están configurados en tu lista, etc.?
runmad
Además, sé que tengo todo configurado correctamente porque cuando la aplicación está en segundo plano, todo funciona perfectamente. Es solo cuando la aplicación no se está ejecutando que no lo hace.
Papá Noel
Me pregunto si un disparador de lanzamiento de notificación push está determinado por el sistema. Por ejemplo, si iOS determina que no es un buen momento para iniciar la aplicación en este momento, podría posponerla hasta más tarde. ¿Quizás intente cerrar todas las aplicaciones en ejecución / en segundo plano y vea qué sucede? Solo estoy adivinando en este punto: - /
runmad
Solo intenté eso. No pasó nada, como siempre. Podría preguntar en los foros de desarrollo.
Santa Claus
37

La respuesta es SÍ, pero no debe usar 'Recuperación en segundo plano' o 'Notificación remota'. PushKit es la respuesta que deseas.

En resumen, PushKit, el nuevo marco en ios 8, es el nuevo mecanismo de notificación de inserción que puede iniciar silenciosamente su aplicación en segundo plano sin avisos de alerta visual, incluso si su aplicación fue eliminada al deslizar el interruptor de la aplicación, sorprendentemente, incluso no puede verla desde el conmutador de aplicaciones.

Referencia de PushKit de Apple:

El marco PushKit proporciona las clases para que sus aplicaciones iOS reciban notificaciones de servidores remotos. Los empujes pueden ser de dos tipos: estándar y VoIP. Las notificaciones estándar pueden enviar notificaciones al igual que en versiones anteriores de iOS. Las notificaciones de VoIP proporcionan una funcionalidad adicional además de la notificación estándar que se necesita para que las aplicaciones de VoIP realicen el procesamiento a pedido de la notificación antes de mostrar una notificación al usuario.

Para implementar esta nueva función, consulte este tutorial: https://zeropush.com/guide/guide-to-pushkit-and-voip : lo probé en mi dispositivo y funciona como se esperaba.

superZhen
fuente
99
Me parece que tienes que configurar tu aplicación como usando VoIP. Si su aplicación no es realmente una aplicación VoIP, ¿no será rechazada durante la revisión?
duncanc4
66
Desafortunadamente, conociendo el proceso de validación de Apple, sería lógico que la aplicación fuera rechazada.
Kepa Santos
3
Utilizado para VoIP. Si no usa VoIP para el usuario, esto aumentará en gran medida el riesgo de rechazo de revisión.
Chris
Parece que los grandes proveedores están utilizando esta instalación como una excusa para ejecutar cosas en segundo plano y Apple está haciendo la vista gorda. Convertirse en Android una característica a la vez.
TCB13
PushKit está reservado para VoIP, proveedores de archivos y complicaciones de reloj. No está disponible para los casos de uso que describe esta respuesta.
quellish
15

En realidad, si necesita probar la recuperación en segundo plano, debe habilitar una opción en el esquema:

habilitar bg fetch

Otra forma de probarlo: simular bg fetch

Aquí hay información completa sobre esta nueva característica: http://www.objc.io/issue-5/multitasking.html

Danil
fuente
4

He estado probando diferentes variantes de esto durante días, y pensé que por un día tuve que volver a iniciar la aplicación en segundo plano, incluso cuando el usuario se deslizó para matar, pero no, no puedo replicar ese comportamiento.

Es lamentable que el comportamiento sea bastante diferente al anterior. En iOS 6, si eliminas la aplicación de los íconos que se mueven, aún se volverá a despertar con los activadores SLC. Ahora, si matas al deslizar, eso no sucede.

Es un comportamiento diferente, y el usuario, que continuaría obteniendo información útil de nuestra aplicación si la hubiera matado en iOS 6, ahora no lo hará.

Necesitamos empujar a nuestros usuarios para que vuelvan a abrir la aplicación ahora si han deslizado para matarla y todavía esperan algunos de los comportamientos de notificación que solíamos darles. Me preocupa que esto no sea obvio para los usuarios cuando deslizan una aplicación. Después de todo, pueden estar básicamente limpiando o queriendo reorganizar las aplicaciones que se muestran minimizadas.

snarshad
fuente
2
Eso es exactamente lo que hicimos (applicationWillTerminate), pero no creo que diera la notificación durante las purgas de memoria, al menos no en iOS 7. Noté que mostraba la notificación justo antes de reiniciar para una actualización del sistema operativo, pero eso es así raro no parecía tan malo.
snarshad
"En iOS 6, si eliminaste la aplicación de los íconos que se movían, aún se reavivaría con los activadores de SLC. Ahora, si matas con solo deslizar, eso no sucede". Esto ahora sucede, fue una regresión temporal en una versión anterior de iOS 7.
funkybro
3

Esto podría ayudarte

En la mayoría de los casos, el sistema no relanza las aplicaciones después de que el usuario las cierra forzosamente. Una excepción son las aplicaciones de ubicación, que en iOS 8 y versiones posteriores se relanzan después de que el usuario las cierre forzosamente. Sin embargo, en otros casos, el usuario debe iniciar la aplicación explícitamente o reiniciar el dispositivo antes de que el sistema pueda iniciar automáticamente la aplicación en segundo plano. Cuando la protección con contraseña está habilitada en el dispositivo, el sistema no inicia una aplicación en segundo plano antes de que el usuario desbloquee el dispositivo por primera vez.

Fuente: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

Stanislav S.
fuente
3
For **iOS13**

For background PUSHES in iOS13 you must set below parameters
apns-priority = 5
apns-push-type = background
Required for WatchOS
Highly recommended for Other platforms 

Empujes de fondo El enlace del video: https://developer.apple.com/videos/play/wwdc2019/707/

CrazyPro007
fuente
¿Me pueden compartir el enlace del video por favor?
guhan0