IOS avvierà la mia app in background se è stata forzatamente chiusa dall'utente?


219

Sto attivando un recupero in background utilizzando la content-availablebandiera su una notifica push. Ho il fetche remote-notification UIBackgroundModesabilitato.

Ecco l'implementazione che sto usando nel mio 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);

}

Quando l'app è in esecuzione in background, funziona benissimo. (La notifica viene ricevuta e l'app ha attivato la notifica locale "sembra che ho ricevuto una notifica", come dovrebbe fare il codice sopra).

Tuttavia, quando l'app non è in esecuzione e viene ricevuta una notifica push con il content-availableflag, l'app non viene avviata e il didRecieveRemoteNotificationmetodo delegato non viene mai chiamato.

Il video del WWDC Novità del multitasking (n. 204 del WWDC 2013) mostra questo:inserisci qui la descrizione dell'immagine

Dice che l'applicazione viene "lanciata in background" quando viene ricevuta una notifica push con il content-availableflag.

Perché la mia app non si avvia in background?

Quindi la vera domanda è:

IOS eseguirà attività in background dopo che l'utente ha chiuso forzatamente l'app?


Come stai controllando se l'app si avvia in background?
runmad,

1
@Runmad Accedo un mucchio di merda- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Babbo Natale,

Come lo stai registrando, solo NSLog? Dovrai impostare Avvio su manuale nelle impostazioni dello schema dell'app (vedi risposta)
runmad,

@runmad vedi commento sulla risposta
Babbo Natale,

@HaimBenchimol Hai ricevuto una risposta alla tua segnalazione di bug? Non sono riuscito a presentare la mia segnalazione di bug.
Babbo Natale,

Risposte:


215

UPDATE2:

È possibile ottenere ciò utilizzando il nuovo framework PushKit, introdotto in iOS 8. Sebbene PushKit sia utilizzato per VoIP. Quindi il tuo utilizzo dovrebbe essere legato al VoIP, altrimenti c'è il rischio di rifiuto dell'app. (Vedi questa risposta ).


UDPDATE1:

La documentazione è stata chiarita per iOS8 . La documentazione può essere letta qui . Ecco un estratto rilevante:

Utilizza questo metodo per elaborare le notifiche remote in arrivo per la tua app. A differenza del application:didReceiveRemoteNotification:metodo, che viene chiamato solo quando l'app è in esecuzione in primo piano, il sistema chiama questo metodo quando l'app è in esecuzione in primo piano o in background. Inoltre, se hai attivato la modalità in background delle notifiche remote, il sistema avvia la tua app (o la riattiva dallo stato sospeso) e la mette in background quando arriva una notifica push. Tuttavia, il sistema non avvia automaticamente la tua app se l'utente l'ha forzata ad uscire. In tale situazione, l'utente deve riavviare l'app o riavviare il dispositivo prima che il sistema tenti di riavviare l'app automaticamente.


Sebbene ciò non sia stato chiarito dal video del WWDC, una rapida ricerca nei forum degli sviluppatori ha rivelato questo:

https://devforums.apple.com/message/873265#873265 (è richiesto il login)

Inoltre, tieni presente che se uccidi la tua app dallo switcher (ovvero scorri verso l'alto per uccidere l'app), il sistema operativo non riavvierà mai l'app indipendentemente dalla notifica push o dal recupero in background. In questo caso l'utente deve riavviare manualmente l'app una volta e da quel momento in poi verranno invocate le attività in background. - Pmarcos

Quel post era di un dipendente Apple, quindi penso di potermi fidare che queste informazioni siano corrette.

Quindi sembra che quando l'app viene uccisa dallo switcher dell'app (scorrendo verso l'alto), l'app non verrà mai avviata, anche per i recuperi in background pianificati.


2
Per me l'aggiunta dell'azione in "didFinishLaunchingWithOptions" quando le opzioni di avvio non sono nulle ha funzionato. Ho lo stesso metodo qui come in "didreceiveRemoteNotification"
harsh.prasad

@ harsh.prasad è interessante. Il problema era che l'app non veniva avviata quando l'app è stata uccisa dal selettore di app.
Babbo Natale,

3
Non è necessario che l'app venga mostrata nel selettore di app se si riceve un push silenzioso. Potrebbe essere avviato in background senza aggiungerlo al selettore di app, e potrebbe essere eseguito e "fare le sue cose" e poi uscire. Le app che rimangono attive troppo a lungo verrebbero uccise nello stesso modo in cui sono già.
MindJuice,

1
@chrizstone La soluzione è che si tratta di un comportamento previsto e non puoi farci nulla.
Babbo Natale,

1
@JPK Uh, le notifiche push stesse non sono interessate. Sta solo eseguendo attività in background che non funzioneranno dopo che è stato chiuso forzatamente.
Babbo Natale,

70

È possibile modificare le impostazioni di avvio del target in "Gestisci schema" in Wait for <app>.app to be launched manually, che consente di eseguire il debug impostando un punto di interruzione application: didReceiveRemoteNotification: fetchCompletionHandler:e inviando la notifica push per attivare l'avvio in background.

Non sono sicuro che risolverà il problema, ma per il momento potrebbe aiutarti con il debug.

immagine dello schermo


quindi questo ha aiutato, ma il problema persiste
Babbo Natale,

Strano. Presumo che tu abbia più che ricontrollato tutti i flash sono impostati nel tuo plist, ecc.?
runmad

Inoltre, so di avere tutto impostato correttamente perché quando l'app è in background, tutto funziona perfettamente. È proprio quando l'app non è in esecuzione affatto che non lo fa.
Babbo Natale,

Mi chiedo se un trigger di avvio della notifica push sia determinato dal sistema. Ad esempio, se iOS determina che non è il momento giusto per avviare l'app in questo momento, potrebbe rimandarla a dopo. Forse prova a chiudere tutte le app in esecuzione / in background e vedere cosa succede? Sto solo indovinando a questo punto: - /
runmad

l'ho appena provato. Non è successo niente, proprio come al solito. Potrei chiedere sui forum di sviluppo.
Babbo Natale,

37

La risposta è SÌ, ma non utilizzare "Recupero sfondo" o "Notifica remota". PushKit è la risposta che desideri.

In breve, PushKit, il nuovo framework di iOS 8, è il nuovo meccanismo di notifica push che può avviare silenziosamente la tua app in background senza alcun avviso visivo anche se la tua app è stata uccisa scorrendo dallo switcher di app, sorprendentemente non puoi nemmeno vederla dal commutatore di app.

Riferimento PushKit di Apple:

Il framework PushKit fornisce le classi per le tue app iOS per ricevere push dai server remoti. I push possono essere di due tipi: standard e VoIP. I push standard possono inviare notifiche proprio come nelle versioni precedenti di iOS. I push VoIP forniscono funzionalità aggiuntive oltre al push standard necessario alle app VoIP per eseguire l'elaborazione su richiesta del push prima di visualizzare una notifica all'utente.

Per distribuire questa nuova funzionalità, consultare questo tutorial: https://zeropush.com/guide/guide-to-pushkit-and-voip : l' ho testato sul mio dispositivo e funziona come previsto.


9
Mi sembra che devi impostare la tua app come usando VoIP. Se la tua app non è in realtà un'app VoIP, non verrà rifiutata durante la revisione?
duncanc4,

6
Sfortunatamente, conoscendo il processo di convalida di Apple, sarebbe logico che l'applicazione fosse respinta.
Kepa Santos,

3
Utilizzato per VoIP. Se non si utilizza VoIP per l'utente, ciò aumenterà notevolmente il rischio di rifiuto della revisione.
Chris,

Sembra che i grandi fornitori stiano usando questa funzione come scusa per eseguire roba in background e Apple sta chiudendo un occhio. Diventando Android una funzionalità al momento.
TCB13

PushKit è riservato a VoIP, Provider di file e Complicazioni dell'orologio. Non è disponibile per i casi d'uso descritti in questa risposta.
Quellish,


4

Ho provato diverse varianti di questo per giorni e ho pensato per un giorno di averlo riavviato l'app in background, anche quando l'utente ha strisciato per uccidere, ma no non riesco a replicare quel comportamento.

È un peccato che il comportamento sia piuttosto diverso rispetto a prima. Su iOS 6, se hai ucciso l'app dalle icone jiggling, verrebbe comunque risvegliata sui trigger SLC. Ora, se uccidi scorrendo, ciò non accade.

È un comportamento diverso e l'utente, che continuerebbe a ottenere informazioni utili dalla nostra app se le avesse uccise su iOS 6, ora non lo farà.

Dobbiamo spingere i nostri utenti a riaprire l'app ora se hanno fatto scorrere per ucciderla e si stanno ancora aspettando alcuni dei comportamenti di notifica che abbiamo usato per dare loro. Temo che questo non sarà ovvio per gli utenti quando trascinano via un'app. Dopotutto, potrebbero sostanzialmente ripulire o voler riorganizzare le app mostrate minimizzate.


2
Questo è esattamente quello che abbiamo fatto (applicationWillTerminate), ma non credo che abbia dato la notifica durante l'eliminazione della memoria, almeno non su iOS 7. Ho notato che mostrava la notifica subito prima del riavvio per un aggiornamento del sistema operativo, ma è così raro non sembrava troppo male.
snarshad

"Su iOS 6, se avessi ucciso l'app dalle icone di jiggling, sarebbe comunque risvegliata sui trigger SLC. Ora, se uccidi facendo scorrere, ciò non accade." Ciò accade ora, è stata una regressione temporanea in una prima versione di iOS 7.
funkybro,

3

Questo potrebbe aiutarti

Nella maggior parte dei casi, il sistema non riavvia le app dopo che sono state forzatamente chiuse dall'utente. Un'eccezione sono le app di localizzazione, che in iOS 8 e versioni successive vengono riavviate dopo essere state forzate a uscire dall'utente. In altri casi, tuttavia, l'utente deve avviare esplicitamente l'app o riavviare il dispositivo prima che l'app possa essere avviata automaticamente in background dal sistema. Quando la protezione con password è abilitata sul dispositivo, il sistema non avvia un'app in background prima che l'utente sblocchi il dispositivo per la prima volta.

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.