Verhalten für signifikante Änderungsort-API beim Beenden / Anhalten?

108

Dies ist der Abschnitt aus der CLLocationManager- Dokumentation, der das App-Verhalten mit startMonitoringSignificantLocationChanges beschreibt :

Wenn Sie diesen Dienst starten und Ihre Anwendung anschließend beendet wird, startet das System die Anwendung automatisch im Hintergrund neu, wenn ein neues Ereignis eintrifft. In diesem Fall enthält das an die Anwendung übergebene Optionswörterbuch: didFinishLaunchingWithOptions: Die Methode Ihres Anwendungsdelegierten enthält den Schlüssel UIApplicationLaunchOptionsLocationKey, der angibt, dass Ihre Anwendung aufgrund eines Standortereignisses gestartet wurde. Nach dem Neustart müssen Sie weiterhin ein Standortmanagerobjekt konfigurieren und diese Methode aufrufen, um weiterhin Standortereignisse zu empfangen. Wenn Sie die Ortungsdienste neu starten, wird das aktuelle Ereignis sofort an Ihren Delegaten übermittelt. Darüber hinaus wird die Location-Eigenschaft Ihres Location Manager-Objekts mit dem neuesten Location-Objekt gefüllt, noch bevor Sie Location Services starten.

Wenn Ihre App beendet wird (und ich gehe davon aus, dass Sie stopMonitoringSignificantLocationChanges nicht von applicationWillTerminate aus aufrufen ), werden Sie mit einem UIApplicationLaunchOptionsLocationKey- Parameter für application: didFinishLaunchingWithOptions geweckt . Zu diesem Zeitpunkt erstellen Sie Ihren CLLocationManager , rufen startMonitoringSignificantLocationChanges auf und führen die Verarbeitung Ihres Hintergrundstandorts für eine begrenzte Zeit durch . Also bin ich mit diesem Stück in Ordnung.

Der vorherige Absatz beschreibt nur, was passiert, wenn die App beendet wird. Er schlägt nicht vor, was Sie tun, wenn die Anwendung angehalten wird. In der Dokumentation zu didFinishLaunchingWithOptions heißt es:

Die Anwendung verfolgt Standortaktualisierungen im Hintergrund, wurde gelöscht und wurde jetzt neu gestartet. In diesem Fall enthält das Wörterbuch einen Schlüssel, der angibt, dass die Anwendung aufgrund eines neuen Standortereignisses neu gestartet wurde.

Es wird vorgeschlagen, dass Sie diesen Anruf erst erhalten, wenn Ihre App (aufgrund einer Standortänderung) nach Beendigung gestartet wird.

Der Absatz über den Dienst für wesentliche Änderungen im Programmierhandbuch zur Standortaufklärung enthält jedoch Folgendes:

Wenn Sie diesen Dienst laufen lassen und Ihre Anwendung anschließend angehalten oder beendet wird, aktiviert der Dienst Ihre Anwendung automatisch, wenn neue Standortdaten eintreffen. Zum Zeitpunkt des Aufwachens wird Ihre Anwendung in den Hintergrund gestellt und erhält eine kleine Zeitspanne für die Verarbeitung der Standortdaten. Da sich Ihre Anwendung im Hintergrund befindet, sollte sie nur minimale Arbeit leisten und alle Aufgaben (z. B. das Abfragen des Netzwerks) vermeiden, die möglicherweise verhindern, dass sie vor Ablauf der zugewiesenen Zeit zurückkehrt. Ist dies nicht der Fall, wird Ihre Anwendung möglicherweise beendet.

Dies deutet darauf hin, dass Sie mit Standortdaten geweckt werden, wenn Ihre App angehalten wurde, ohne jedoch zu erwähnen, wie Sie geweckt wurden:

Während ich dies aufschreibe, denke ich, dass ich vielleicht gerade meine eigene Frage beantwortet habe, aber es wäre großartig, wenn mein Verständnis davon von jemandem bestätigt würde, der besser informiert ist.

RedBlueThing
quelle

Antworten:

80

Seit ich diese Frage gestellt habe, habe ich einige Tests durchgeführt (hauptsächlich im Zug zwischen Zuhause und Arbeit) und bestätigt, dass das Verhalten für angehaltene Apps so ist, wie ich es am Ende der Frage vermutet habe.

Das heißt, Ihre angehaltene App wird aktiviert. Sie erhalten keine Rückrufe von Ihrem App-Delegaten. Stattdessen erhalten Sie Ihre Standortaktualisierungen über Ihr vorhandenes CLLocationManagerDelegate . Sie können feststellen, dass Sie im Hintergrund ausgeführt werden, indem Sie den applicationState überprüfen und begrenzte Arbeit für den Fall leisten, dass Sie aus einem angehaltenen Zustand geweckt werden, um die Standortverarbeitung durchzuführen.

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

Zu diesem Schluss bin ich mit einem Standorttestkabel gekommen, das Sie gerne herunterladen und ausprobieren können. Es ist eine ziemlich einfache App, mit der Sie wichtige Änderungs- und GPS-Änderungs-APIs über die Benutzeroberfläche aktivieren und alle Antworten protokollieren können, die Sie zurückerhalten.

NB Punkt sechs in der vorherigen Antwort ist nicht korrekt. Gefriergetrocknete angehaltene Apps erhalten CLLocationManagerDelegate- Rückrufe, wenn sie aus einem angehaltenen Zustand geweckt werden.

RedBlueThing
quelle
1
Ich habe # 6 in meiner Antwort gestrichen, um die Leute nicht zu verwirren.
Aaron
Ironischerweise empfand ich die gleiche Verwirrung, als ich mich für die signifikante Veränderung entwickelte. Ich habe immer noch einige Zweifel, was passiert, wenn die App geschlossen wird. Wird der UIApplicationDelegate-Rückruf nicht durchgeführt? ist das der richtige Weg, um die App zu starten. Wenn der Standortmanager noch nicht gestartet wurde, wie kann er die Benachrichtigungen im Hintergrund abrufen? (Zeit für mehr F & E)
Darshansonde
Vielen Dank für die Beispiel-App, sie war sehr nützlich für mich. Ich habe eine Frage: Was passiert, wenn ich den Standard-Ortungsdienst im Hintergrund verwendet habe, nicht den signifikanten, wird die App in diesem Fall auch nach Beendigung neu gestartet? Ich habe diese Frage hier im Detail gestellt. Ich würde mich freuen, wenn Sie mich aufhellen könnten:] stackoverflow.com/questions/12239967/…
aslisabanci
2
Nicht bearbeitet auf ios7 stackoverflow.com/questions/18946881/…
Igor
Wissen Sie, wie lange es gedauert hat, bis Ihre App beendet wurde? Und dann stattdessen einen AppDelegate-Rückruf erhalten? (Ist es wie 30 Minuten? 2 Stunden? 5 Stunden?) Der Grund, warum ich dies frage, ist, dass ich eine zu überwachende Region eingerichtet habe. Ich habe viele Male versucht, meine App zu starten, aber nur einmal musste ich die App neu starten. Das andere Mal der didExitRegionRückruf, aber ich konnte nicht startLocationUpdatesvon dort, da es nicht durch App-Start war ...
Honey
25

Mein Verständnis ist wie folgt (ich bin gerade dabei, eine Anwendung zu schreiben, die auf dieser API basiert, diese Komponente jedoch nicht ausreichend abgeschlossen hat, um mit dem Testen zu beginnen):

  1. Ihre Anwendung wird zum ersten Mal ausgeführt, Sie registrieren sich bei startMonitoringSignificantLocationChanges und stellen eine Rückruffunktion bereit. Während Ihre Anwendung ausgeführt wird, ruft sie diesen Rückruf auf, wenn eine wesentliche Änderung eingeht.
  2. Wenn Ihre Anwendung in den Hintergrund gestellt wird, erhält UIApplication applicationWillResignActive , gefolgt von applicationDidEnterBackground .
  3. Wenn Ihre Anwendung beendet wird, während sie im Hintergrund angehalten wird, werden Sie nicht benachrichtigt. Wenn Ihre Anwendung jedoch während der Ausführung beendet wird (Vordergrund oder Hintergrund meines Wissens), erhalten Sie einen Moment mit applicationWillTerminate . Sie können von dieser Funktion keine zusätzliche Hintergrundzeit anfordern.
  4. Obwohl das Betriebssystem im Hintergrund getötet wurde, wird Ihre Anwendung neu gestartet. Wenn Ihre Anwendung zur Änderung einfach vom Betriebssystem gestartet wird, erhalten Sie einen Aufruf der Anwendung didFinishLaunchingWithOptions :

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])

    hilft Ihnen festzustellen, ob Sie von einer Änderung des Hintergrundstandorts zurückgekehrt sind.

  5. Wenn Sie stattdessen gerade im Hintergrund ausgeführt wurden und Ihre App vom Benutzer manuell neu gestartet wird, erhalten Sie eine applicationWillEnterForeground gefolgt von applicationDidBecomeActive .
  6. Unabhängig davon, wie es passiert ist, müssen Sie beim Neustart Ihrer Anwendung (es sei denn, sie wurde aufgrund einer Hintergrundaufgabe noch im Hintergrund ausgeführt und die Aufgabe hat begonnen, Änderungen zu überwachen) explizit anweisen , dass sieMonitoringSignificantLocationChanges erneut starten soll , da der Rückruf Nein lautet länger angebracht nach "Gefriertrocknung". Und ja, Sie müssen nur Code in didUpdateToLocation implementieren, sobald Sie einen Standort-Handler erneut angehängt haben, sobald Sie aus dem angehaltenen Zustand zurückgekehrt sind.

Dies ist, was ich gerade mit meiner Code-Entwicklung mache. Wie ich bereits erwähnt habe, bin ich noch nicht bereit, dies auf einem Gerät zu testen. Daher kann ich nicht sagen, ob ich alles richtig interpretiert habe. Kommentatoren, bitte zögern Sie nicht, mich zu korrigieren Thema).

Oh, und wenn Sie durch einen Pechstrich eine App veröffentlichen, die das tut, was ich will, könnte ich weinen :)

Viel Glück!

Aaron
quelle
1
@Tegeril +1 Danke für die Antwort. Ich fing an, Grillen zu hören. :) Ich bin überrascht, dass Apps, die angehalten wurden, startMonitoringSignificantLocationChanges erneut aufrufen müssen. Haben Sie einen Link zum Dokument, in dem dies beschrieben wird? Mein Verständnis war, dass das Laden aus einem angehaltenen Zustand alle Ihre Objekte so instanziiert, wie sie waren, als die App angehalten wurde. Ich würde also erwarten, dass die wesentliche Änderungsanforderung in Kraft tritt.
RedBlueThing
Sie könnten darüber sprechen? "Nach dem Neustart müssen Sie weiterhin ein Standortmanagerobjekt konfigurieren und diese Methode aufrufen, um weiterhin Standortereignisse zu empfangen." Ich denke, dies bezieht sich auf den Fall, in dem Ihre App aus einem abgeschlossenen Zustand (durch ein Standortereignis) gestartet wurde. Dies ist im Grunde die Wurzel meiner Frage: "Was passiert mit dem suspendierten Fall?".
RedBlueThing
Morgan Grainger in den Dev-Foren schlug Folgendes vor: "Sie müssen einen CLLocationManager erstellen, einen Delegaten festlegen und startMonitoringSignificantLocationChanges aufrufen, wenn Ihre Anwendung gestartet wird. Andernfalls kann Core Location die Updates nirgendwo bereitstellen." im Zusammenhang mit dem Neustart einer Anwendung unabhängig von einem beendeten oder angehaltenen Zustand. Von "App wurde nach startMonitoringSignificantLocationChanges neu gestartet und was nun?"
Aaron
Ich bin damit einverstanden, dass dies auch im Kontext dieses Forumsbeitrags noch vage sein kann (auf dem Poster wurde das Aufwachen aus dem Hintergrund erörtert, aber Morgan verwendete den allgemeineren Neustart einer Anwendung). Ich denke immer noch, dass Sie anrufen müssen, um erneut zu überwachen, wenn Ihre Anwendung neu gestartet wird, wenn Sie mit der Funktion für wesentliche Änderungen arbeiten möchten. Wenn Sie stattdessen eine Hintergrundaufgabe starten und mit dem Standard-Ortungsdienst und der GPS-Funktionalität aktualisieren möchten, ist dies eine alternative Option. Ich glaube nicht, dass Sie sich bei jedem Start mit wesentlichen Änderungen neu registrieren müssen, um erneut gestartet zu werden.
Aaron
1
Ich bin froh, dass daraus etwas Bestimmtes hervorgegangen ist, das mir in Zukunft helfen sollte :)
Aaron
1

Wenn die Anwendung aufgrund eines Standortwechsels aus dem angehaltenen Zustand aufgerufen wird, wird die Anwendung im Hintergrundzustand gestartet.

Alle Objekte sind live und Sie erhalten eine Standortaktualisierung im vorhandenen Delegaten.

Anshu
quelle