webentwicklung-frage-antwort-db.com.de

Hintergrundstandortdienste funktionieren nicht unter iOS 7

Ich habe kürzlich meine iOS-Geräte für iOS 7 aktualisiert. Eine der Apps, die wir entwickeln, verwendet Hintergrundortungsdienste, um den Standort des Geräts zu ermitteln. Alle Tester haben berichtet, dass die App unter iOS nicht mehr im Hintergrund zu verfolgen scheint 7. 

Wir haben überprüft, dass das Hintergrunding für die App in den Einstellungen auf dem Gerät aktiviert ist und der vorherige Build unter iOS 6 einwandfrei funktionierte. Selbst wenn das Gerät getaktet wurde, wurde die App nach einem Standort-Update neu gestartet. 

Gibt es noch etwas, was getan werden muss, damit dies unter iOS 7 funktioniert? 

34
Alan Samet

Hier ist die Lösung, die ich verwendet habe, um fortlaufende Positionen von iOS 7-Geräten zu erhalten, unabhängig davon, ob sie im Vordergrund oder Hintergrund sind.

Die vollständige Lösung und Erklärung finden Sie im Blog und auch bei github: -

  1. Programm zum Aktualisieren der Hintergrundposition für iOS 7 und 8

  2. Github-Projekt: Programmierung der Hintergrundortaktualisierung für iOS 7 und 8

Methoden und Erklärung: -

  1. Ich starte den Location Manager alle 1 Minute in Funktion didUpdateLocations neu.

  2. Ich erlaube dem Standortmanager, die Standorte 10 Sekunden lang vom Gerät abzurufen, bevor er heruntergefahren wird (um Batterie zu sparen).

Teilcode unten: -

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{

for(int i=0;i<locations.count;i++){
    CLLocation * newLocation = [locations objectAtIndex:i];
    CLLocationCoordinate2D theLocation = newLocation.coordinate;
    CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];

    if (locationAge > 30.0)
        continue;

    //Select only valid location and also location with good accuracy
    if(newLocation!=nil&&theAccuracy>0
       &&theAccuracy<2000
       &&(!(theLocation.latitude==0.0&&theLocation.longitude==0.0))){
        self.myLastLocation = theLocation;
        self.myLastLocationAccuracy= theAccuracy;
        NSMutableDictionary * dict = [[NSMutableDictionary alloc]init];
        [dict setObject:[NSNumber numberWithFloat:theLocation.latitude] forKey:@"latitude"];
        [dict setObject:[NSNumber numberWithFloat:theLocation.longitude] forKey:@"longitude"];
        [dict setObject:[NSNumber numberWithFloat:theAccuracy] forKey:@"theAccuracy"];
        //Add the vallid location with good accuracy into an array
        //Every 1 minute, I will select the best location based on accuracy and send to server
        [self.shareModel.myLocationArray addObject:dict];
    }
}

//If the timer still valid, return it (Will not run the code below)
if (self.shareModel.timer)
    return;

self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager];
[self.shareModel.bgTask beginNewBackgroundTask];

//Restart the locationMaanger after 1 minute
self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self
                                                       selector:@selector(restartLocationUpdates)
                                                       userInfo:nil
                                                        repeats:NO];

//Will only stop the locationManager after 10 seconds, so that we can get some accurate locations
//The location manager will only operate for 10 seconds to save battery
NSTimer * delay10Seconds;
delay10Seconds = [NSTimer scheduledTimerWithTimeInterval:10 target:self
                                                selector:@selector(stopLocationDelayBy10Seconds)
                                                userInfo:nil
                                                 repeats:NO];
 }

Update vom Mai 2014: Ich erhielt einige Anfragen zum Hinzufügen von Beispielcodes beim Senden des Standorts an den Server für ein bestimmtes Zeitintervall. Ich habe die Beispielcodes hinzugefügt und außerdem einen Fix für BackgroundTaskManager hinzugefügt, um eine Störung für den Hintergrund zu lösen, der über einen längeren Zeitraum ausgeführt wird. Wenn Sie Fragen haben, sind Sie herzlich eingeladen, an einer Diskussion hier teilzunehmen: Programmierung der Hintergrundaktualisierung für iOS 7 mit Standortaktualisierung für die Serverdiskussion

Update vom Januar 2015: Wenn Sie die Standortaktualisierung auch erhalten möchten, wenn die App angehalten ist, lesen Sie bitte die folgenden Informationen: Standortaktualisierungen für iOS-App abrufen, auch wenn sie angehalten sind

47
Ricky

Wenn Sie sich das WWDC 2013 Session-Video Nr. 204 ansehen - Was ist neu beim Multitasking-PDF ?, wird auf Seite 15 eindeutig erwähnt, dass Apps nicht im Hintergrund gestartet werden, wenn der Benutzer sie mit dem App-Umschalter beendet. Bitte sehen Sie das Bild,

enter image description here

18
Obj-Swift

Ich denke, sie haben eine Optimierung vorgenommen (wahrscheinlich mithilfe von Bewegungssensoren), um eine "relativ" stationäre Positionierung des Telefons zu erkennen und die Standortaktualisierungen zu stoppen. Dies ist nur eine Spekulation, aber meine Tests zeigen aktuell:

  1. Standortaktualisierungen starten; (getestet mit einer Genauigkeit von 10 und 100 Metern, jeweils dreimal)
  2. Schalten Sie den Bildschirm des Geräts aus, um die App in den Hintergrund zu stellen.
  3. Lassen Sie das Gerät 30 Minuten lang stehen (z. B. auf einem Schreibtisch).

Die Daten, die ich protokolliere, zeigen, dass die Geo-Updates nach ~ 15m und 30s nicht mehr erscheinen. Damit ist auch alle andere Hintergrundverarbeitung, die Sie durchführen, beendet.

Mein Gerät ist iPhone 5 mit iOS 7.

Ich bin zu 95% sicher, das war unter iOS 6/6.1 nicht der Fall. Hier erhalten Sie Geo-Updates mit einer Genauigkeit von 100 m, um den kontinuierlichen Betrieb im Hintergrund zu ermöglichen.

Update

Wenn Sie den Location Manager alle 8 Minuten neu starten, sollte er kontinuierlich ausgeführt werden.

Update Nr. 2

Ich habe dies nicht zuletzt getestet, aber so habe ich es neu gestartet, als ich den Beitrag schrieb. Ich hoffe das ist hilfreich.

- (void)tryRestartLocationManager
{
    NSTimeInterval now = [[NSDate date] timeIntervalSince1970];

    int seconds = round(floor(now - locationManagerStartTimestamp));

    if ( seconds > (60 * 8) ) {
        [locationManager stopUpdatingLocation];
        [locationManager startUpdatingLocation];
        locationManagerStartTimestamp = now;
    }
}
16
Nikolay Tsenkov

Eine meiner iOS-Apps muss in regelmäßigen Abständen Standortaktualisierungen an den Server senden.

Ab iOS 7 beginnen

  • eine App muss bereits standortbezogene Dienste verwendet haben .__ (startUpdatingLocation), BEVOR der Hintergrund für die Hintergrundlaufzeit von .__
  • das Timeout der Hintergrundzeit wurde von 10 Minuten auf 3 Minuten reduziert
  • durch das Stoppen der Standortaktualisierungen (über stopUpdatingLocation) wird der 3 Minute backgroundTimeRemaining-Countdown gestartet
  • startstandortaktualisierungen, die sich bereits im Hintergrund befinden, setzen die backgroundTimeRemaining-Funktion nicht zurück

STOPPEN Sie die Standortaktualisierungen daher NICHT zu jeder Zeit. Verwenden Sie stattdessen die erforderliche Genauigkeit (feine Positionierung vs. grobe Position). Der grobe Standort verbraucht nicht viel Batterie ... daher löst diese Lösung Ihr Problem.

Nach langem Suchen im Internet wurde ein Link gefunden, der eine praktikable Lösung für iOS 7 bietet. Die Lösung sieht wie folgt aus:

  • Starten Sie die Standortaktualisierungen .__ (startUpdatingLocation), legen Sie jedoch die Genauigkeits- und Entfernungsfilter auf .................. Dies ist wichtigim Vordergrund (in applicationDidEnterBackground ist zu spät).
  • Wenn eine feinkörnige Auflösung erforderlich ist, stellen Sie vorübergehend die Filter für die Genauigkeit und Entfernung ein, um den bestmöglichen Standort zu erhalten. Anschließend setzen Sie sie wieder auf die kursabhängigen Werte zurück. Stoppen Sie jedoch niemals
  • Da Standortaktualisierungen immer aktiviert sind, wird die Anwendung Nicht unterbrochen, wenn sie in den Hintergrund wechselt.

Stellen Sie sicher, dass Sie der Info.plist "Location" der Anwendung den Schlüssel "UIBackgroundModes" .__ "location-services" und "gps" zum UIRequiredDeviceCapabilities-Schlüssel hinzufügen

Credits: http://gooddevbaddev.wordpress.com/2013/10/22/ios-7-running-location-based-apps-in-the-background/

7
androidExplorer

Ich habe einen anderen Thread Start Location Manager in iOS 7 von Hintergrundaufgabe gefunden Sash hat das erwähnt 

Ich habe das Problem/die Lösung gefunden. Wenn es Zeit ist, den Ortungsdienst zu starten und die Hintergrundaufgabe zu beenden, sollte die Hintergrundaufgabe mit einer Verzögerung angehalten werden (ich habe 1 Sekunde eingestellt). Andernfalls startet der Standortdienst nicht.

Kann jemand das versuchen und überprüfen? 

Nikolay, kannst du deinen Code hier einfügen? Ich habe versucht, den Standortmanager alle 8 Minuten neu zu starten, aber er läuft nicht kontinuierlich.

Update:

Nach der Suche nach High und Low fand ich die Lösung aus dem Apple Forum!

In iOS 7 können Sie kann den Ortungsdienst nicht im Hintergrund starten. Wenn der Ortungsdienst weiterhin im Hintergrund ausgeführt werden soll, müssen Sie ihn im Vordergrund starten. Er wird weiterhin im Hintergrund ausgeführt. 

Wenn Sie wie ich waren, stoppen Sie den Ortungsdienst und starten Sie ihn mit einem Timer im Hintergrund neu. Er funktioniert NICHT. 

Für detailliertere Informationen können Sie die ersten 8 Minuten des Videos 307 der WWDC 2013 ansehen: https://developer.Apple.com/wwdc/videos/

Update vom Februar 2014:.__: Ich kann die Position des Geräts unter Verwendung von iOS 7 nach einigen Monaten des Versuchs kontinuierlich abrufen. Sie finden die vollständige Antwort hier: Hintergrund-Ortungsdienste funktionieren nicht in iOS 7

5
Ricky

Ist das Symbol in der Statusleiste aktiviert? Es war ein seltsames Verhalten, das ich auch hatte ... Überprüfe meine Frage: startMonitoringSignificantLocationChanges, aber nach einiger Zeit wird didUpdateLocations nicht mehr aufgerufen

Ich stellte fest, dass die signifikanten Standortänderungen aktiv waren, aber durch das Stoppen und Neustarten des Dienstes (für erhebliche Änderungen) wurden keine neuen Standorte ausgelöst.

1
Mr. Cobblepot

Sie müssen die pausesLocationUpdatesAutomatically-Eigenschaft von CLLocationManagerclass auf false setzen, damit das System die Standortaktualisierungen nicht anhalten kann.

0
Tibin Thomas