Wird iOS meine App im Hintergrund starten, wenn sie vom Benutzer zwangsweise beendet wurde?

219

Ich löse einen Hintergrundabruf aus, indem ich das content-availableFlag in einer Push-Benachrichtigung verwende. Ich habe das fetchund remote-notification UIBackgroundModesaktiviert.

Hier ist die Implementierung, die ich in meinem AppDelegate.m verwende:

- (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);

}

Wenn die App im Hintergrund ausgeführt wird, funktioniert sie einwandfrei. (Die Benachrichtigung wird empfangen und die App hat die lokale Benachrichtigung "Es sieht so aus, als hätte ich eine Benachrichtigung erhalten" ausgelöst, wie es der obige Code tun sollte.)

Allerdings , wenn die App nicht läuft und eine Push - Benachrichtigung mit der empfangenen content-availableFlagge, wird die App nicht gestartet und die didRecieveRemoteNotificationdelegierte Methode nie aufgerufen.

Das WWDC-Video Was ist neu mit Multitasking (# 204 von WWDC 2013) zeigt dies:Geben Sie hier die Bildbeschreibung ein

Es heißt, dass die Anwendung "im Hintergrund gestartet" wird, wenn eine Push-Benachrichtigung mit dem content-availableFlag empfangen wird .

Warum wird meine App nicht im Hintergrund gestartet?

Die eigentliche Frage lautet also:

Führt iOS Hintergrundaufgaben aus, nachdem der Benutzer die App zwangsweise beendet hat?

Weihnachtsmann
quelle
Wie überprüfen Sie, ob die App im Hintergrund gestartet wird?
Runmad
1
@ Runmad Ich logge ein paar Mist in- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Santa Claus
Wie protokollierst du es, nur NSLog? Sie müssen den Start in Ihren App-Schema-Einstellungen auf manuell einstellen (siehe Antwort)
runmad
@ Runmad siehe Kommentar zur Antwort
Santa Claus
@HaimBenchimol Djd hast du eine Antwort auf deinen Fehlerbericht? Ich bin nicht dazu gekommen, meinen eigenen Fehlerbericht einzureichen.
Weihnachtsmann

Antworten:

215

UPDATE2:

Sie können dies mit dem neuen PushKit-Framework erreichen, das in iOS 8 eingeführt wurde. PushKit wird jedoch für VoIP verwendet. Daher sollte Ihre Nutzung für VoIP erfolgen, da sonst die Gefahr einer Ablehnung der App besteht. (Siehe diese Antwort ).


UDPDATE1:

Die Dokumentation wurde für iOS8 geklärt . Die Dokumentation kann hier gelesen werden . Hier ist ein relevanter Auszug:

Verwenden Sie diese Methode, um eingehende Remote-Benachrichtigungen für Ihre App zu verarbeiten. Im Gegensatz zu der application:didReceiveRemoteNotification:Methode, die nur aufgerufen wird, wenn Ihre App im Vordergrund ausgeführt wird, ruft das System diese Methode auf, wenn Ihre App im Vordergrund oder Hintergrund ausgeführt wird. Wenn Sie den Hintergrundmodus für Remote-Benachrichtigungen aktiviert haben, startet das System Ihre App (oder weckt sie aus dem angehaltenen Zustand) und versetzt sie in den Hintergrundzustand, wenn eine Push-Benachrichtigung eintrifft. Das System startet Ihre App jedoch nicht automatisch, wenn der Benutzer sie zwangsweise beendet hat. In diesem Fall muss der Benutzer Ihre App neu starten oder das Gerät neu starten, bevor das System versucht, Ihre App automatisch erneut zu starten.


Obwohl dies im WWDC-Video nicht klargestellt wurde, ergab eine schnelle Suche in den Entwicklerforen Folgendes:

https://devforums.apple.com/message/873265#873265 (Anmeldung erforderlich)

Beachten Sie auch, dass das Betriebssystem die App unabhängig von der Push-Benachrichtigung oder dem Hintergrundabruf niemals neu startet, wenn Sie Ihre App über den App-Umschalter beenden (dh nach oben wischen, um die App zu beenden). In diesem Fall muss der Benutzer die App einmal manuell neu starten. Ab diesem Zeitpunkt werden die Hintergrundaktivitäten aufgerufen. - pmarcos

Dieser Beitrag wurde von einem Apple-Mitarbeiter verfasst, daher kann ich darauf vertrauen, dass diese Informationen korrekt sind.

Es sieht also so aus, als würde die App niemals gestartet, wenn die App über den App-Umschalter beendet wird (durch Wischen nach oben), selbst für geplante Hintergrundabrufe.

Weihnachtsmann
quelle
2
Für mich hat das Hinzufügen der Aktion in "didFinishLaunchingWithOptions" beim Starten von Optionen nicht funktioniert. Ich habe hier die gleiche Methode wie in "didreceiveRemoteNotification"
harsch.prasad
@ harsch.prasad das ist interessant. Das Problem war, dass die App nicht gestartet wird, wenn die App über den App-Umschalter beendet wurde.
Weihnachtsmann
3
Die App muss nicht im App-Umschalter angezeigt werden, wenn ein stiller Push empfangen wird. Es könnte im Hintergrund gestartet werden, ohne es dem App-Umschalter hinzuzufügen, und es könnte ausgeführt werden und "sein Ding machen" und dann beenden. Apps, die zu lange aktiv bleiben, werden auf die gleiche Weise getötet, wie sie es bereits sind.
MindJuice
1
@chrizstone Die Lösung ist, dass dies beabsichtigtes Verhalten ist und Sie nichts dagegen tun können.
Weihnachtsmann
1
@JPK Äh, Push-Benachrichtigungen selbst sind nicht betroffen. Es werden nur Hintergrundaufgaben ausgeführt, die nach dem erzwungenen Beenden nicht mehr funktionieren.
Weihnachtsmann
70

Sie können die Starteinstellungen Ihres Ziels unter "Schema verwalten" in ändern. Dies Wait for <app>.app to be launched manuallyermöglicht Ihnen das Debuggen, indem Sie einen Haltepunkt festlegen application: didReceiveRemoteNotification: fetchCompletionHandler:und die Push-Benachrichtigung senden, um den Hintergrundstart auszulösen.

Ich bin nicht sicher, ob es das Problem lösen wird, aber es kann Ihnen beim Debuggen vorerst helfen.

Bildschirmfoto

runmad
quelle
Das hat geholfen, aber das Problem besteht immer noch
Santa Claus
Seltsam. Ich nehme an, Sie haben mehr als doppelt überprüft, ob alle Blitze in Ihrer Liste usw. eingestellt sind.
Runmad
Außerdem weiß ich, dass ich alles richtig eingestellt habe, denn wenn die App im Hintergrund ist, funktioniert alles perfekt. Es ist nur, wenn die App überhaupt nicht läuft, was es nicht tut.
Weihnachtsmann
Ich frage mich, ob ein Push-Benachrichtigungs-Startauslöser vom System bestimmt wird. Wenn iOS beispielsweise feststellt, dass es kein guter Zeitpunkt ist, die App jetzt zu starten, wird sie möglicherweise auf einen späteren Zeitpunkt verschoben. Versuchen Sie vielleicht, alle laufenden / Hintergrund-Apps zu schließen und zu sehen, was passiert? Ich
vermute
habe das gerade versucht. Nichts passierte wie immer. Ich könnte in Entwicklerforen fragen.
Weihnachtsmann
37

Die Antwort lautet JA, sollte jedoch nicht "Hintergrundabruf" oder "Remote-Benachrichtigung" verwenden. PushKit ist die Antwort, die Sie wünschen.

Zusammenfassend ist PushKit, das neue Framework in ios 8, der neue Push-Benachrichtigungsmechanismus, mit dem Sie Ihre App ohne visuelle Warnmeldung im Hintergrund starten können, selbst wenn Ihre App durch Herauswischen aus dem App Switcher getötet wurde. Erstaunlicherweise können Sie sie nicht einmal sehen vom App Switcher.

PushKit-Referenz von Apple:

Das PushKit-Framework bietet die Klassen für Ihre iOS-Apps, um Pushs von Remoteservern zu empfangen. Es gibt zwei Arten von Pushs: Standard und VoIP. Standard-Pushs können Benachrichtigungen wie in früheren Versionen von iOS liefern. VoIP-Pushs bieten zusätzliche Funktionen zusätzlich zu den Standard-Pushs, die VoIP-Apps benötigen, um die Push-Verarbeitung bei Bedarf durchzuführen, bevor dem Benutzer eine Benachrichtigung angezeigt wird.

Informationen zum Bereitstellen dieser neuen Funktion finden Sie in diesem Lernprogramm: https://zeropush.com/guide/guide-to-pushkit-and-voip - Ich habe sie auf meinem Gerät getestet und sie funktioniert wie erwartet.

superZhen
quelle
9
Sieht für mich so aus, als müssten Sie Ihre App auf VoIP einstellen. Wenn Ihre App eigentlich keine VoIP-App ist, wird sie dann nicht einfach während der Überprüfung abgelehnt?
Duncanc4
6
Wenn man den Validierungsprozess von Apple kennt, ist es leider logisch, dass der Antrag abgelehnt wurde.
Kepa Santos
3
Wird für VoIP verwendet. Wenn VoIP nicht für den Benutzer verwendet wird, erhöht sich das Risiko einer Ablehnung der Überprüfung erheblich.
Chris
Es sieht so aus, als würden große Anbieter diese Funktion als Ausrede verwenden, um Dinge im Hintergrund auszuführen, und Apple hat ein Auge zugedrückt. Werden Sie Android eine Funktion zu der Zeit.
TCB13
PushKit ist für VoIP, Dateianbieter und Überwachungskomplikationen reserviert. Es ist nicht für die in dieser Antwort beschriebenen Anwendungsfälle verfügbar.
quellish
15

Wenn Sie den Hintergrundabruf testen müssen, müssen Sie eine Option im Schema aktivieren:

bg fetch aktivieren

Eine andere Möglichkeit, wie Sie es testen können: simulieren bg fetch

Hier finden Sie vollständige Informationen zu dieser neuen Funktion: http://www.objc.io/issue-5/multitasking.html

Danil
quelle
4

Ich habe tagelang verschiedene Varianten davon ausprobiert und dachte einen Tag lang, ich hätte die App im Hintergrund neu gestartet, selbst wenn der Benutzer zum Töten gewischt hat, aber nein, ich kann dieses Verhalten nicht replizieren.

Es ist bedauerlich, dass das Verhalten ganz anders ist als zuvor. Wenn Sie unter iOS 6 die App über die wackelnden Symbole beendet haben, wird sie bei SLC-Triggern immer wieder aktiviert. Wenn Sie durch Wischen töten, passiert das nicht.

Es ist ein anderes Verhalten, und der Benutzer, der weiterhin nützliche Informationen von unserer App erhalten würde, wenn er sie unter iOS 6 getötet hätte, wird dies jetzt nicht tun.

Wir müssen unsere Benutzer dazu bewegen, die App jetzt erneut zu öffnen, wenn sie gewischt haben, um sie zu beenden, und immer noch einen Teil des Benachrichtigungsverhaltens erwarten, das wir ihnen früher gegeben haben. Ich mache mir Sorgen, dass dies für Benutzer nicht offensichtlich ist, wenn sie eine App wegwischen. Schließlich können sie im Grunde genommen die angezeigten Apps bereinigen oder neu anordnen.

Snarshad
quelle
2
Genau das haben wir getan (applicationWillTerminate), aber ich glaube nicht, dass es die Benachrichtigung während der Speicherbereinigung gab, zumindest nicht unter iOS 7. Ich habe bemerkt, dass die Benachrichtigung direkt vor einem Neustart für ein Betriebssystem-Upgrade angezeigt wurde, aber das ist so selten schien es nicht so schlimm.
Snarshad
"Wenn Sie unter iOS 6 die App über die wackelnden Symbole beendet haben, wird sie bei SLC-Triggern immer noch wieder aktiviert. Wenn Sie jetzt durch Wischen töten, geschieht dies nicht." Dies geschieht jetzt, es war eine vorübergehende Regression in einer frühen Version von iOS 7.
Funkybro
3

Dies könnte Ihnen helfen

In den meisten Fällen startet das System Apps nicht neu, nachdem sie vom Benutzer zwangsweise beendet wurden. Eine Ausnahme bilden Standort-Apps, die in iOS 8 und höher neu gestartet werden, nachdem sie vom Benutzer zwangsweise beendet wurden. In anderen Fällen muss der Benutzer die App jedoch explizit starten oder das Gerät neu starten, bevor die App vom System automatisch im Hintergrund gestartet werden kann. Wenn der Kennwortschutz auf dem Gerät aktiviert ist, startet das System keine App im Hintergrund, bevor der Benutzer das Gerät zum ersten Mal entsperrt.

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

Stanislav S.
quelle
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 

Hintergrund DRÜCKT Der Videolink: https://developer.apple.com/videos/play/wwdc2019/707/

CrazyPro007
quelle
Kannst du mir bitte den Videolink mitteilen?
Guhan0