2015-09-20 6 views
8

Ich habe eine App, die Benutzer Standort melden müssen, auch wenn es Hintergrund oder sogar getötet (beendet). Das Problem ist, dass die App den Standort nicht seltener als 1 Stunde Intervall melden sollte.iOS periodischen Hintergrund Standort Updates, die nicht nur von signifikanten Standortänderung abhängt

Ich benutze erhebliche Standortänderung (SLC), um alle Bewegungen zu verfolgen, die genug ist, wenn Benutzer unterwegs ist, aber sobald Benutzer stoppt keine weiteren Updates ausgelöst wird und die App keine Gelegenheit hat, neue Position (während Benutzer bleibt in der gleichen Gegend, aber ohne SLC).

Um diesen Fall zu behandeln, fange ich an, Hintergrundabrufe zu verwenden, um Updates-Position regelmäßig im Hintergrund auch ohne SLC zu senden). Das Problem hier ist, dass Hintergrundabrufe oft verwendet wurden (alle 20-30 Minuten, seitdem ich sie in einer anderen iOS 7.x App benutzt habe), aber jetzt mit iOS8/iOS9 kann ich sie nur einmal am Tag bekommen, was nicht akzeptabel ist in meinem Fall. Ich habe viele Tests durchgeführt, eine einfache Hintergrundabruf-App entwickelt, die beim Abruf eine lokale Benachrichtigung hinzufügt. Kein Glück, um es zu zwingen, öfter zu arbeiten.

Hier ist meine AppDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum]; 
    [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]]; 
    return YES; 
} 

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 
{  
    [[UIApplication sharedApplication] cancelAllLocalNotifications]; 
    UILocalNotification *localNotification = [[UILocalNotification alloc] init]; 
    NSDate *now = [NSDate date]; 
    localNotification.fireDate = now; 
    localNotification.alertBody = [NSString stringWithFormat:@"Background fetch!"]; 
    localNotification.soundName = UILocalNotificationDefaultSoundName; 
    NSInteger number = [UIApplication sharedApplication].applicationIconBadgeNumber; 
    number++; 
    localNotification.applicationIconBadgeNumber = number; 
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; 

    completionHandler(UIBackgroundFetchResultNewData); 
} 

Alles, was hier geschehen ist, ist lokale Benachrichtigung auf jedem Hintergrund holen hinzuzufügen. Ich beende immer die Hintergrundausführung mit UIBackgroundFetchResultNewData.

Haben Sie Vorschläge, wie Sie Hintergrundabrufe häufiger zur Arbeit zwingen (oder Verbindungen nachprüfen, die nicht mehr möglich sind)? Irgendwelche alternativen Lösungen, um meine Anforderung zu erfüllen, sind auch willkommen!

+1

Hintergrund Abruf hat noch nie eine Ausführungsdauer garantiert. Ich schlage vor, dass Sie stille Pushs an Ihr Gerät senden, um ihm die Möglichkeit zu geben, den Standort zu melden, aber dies funktioniert nicht, wenn die App beendet wird. – Paulw11

+0

Es wurde nie garantiert, aber zumindest hat es früher öfter funktioniert. Gab es seit iOS 7 einige signifikante Änderungen im Zusammenhang mit Hintergrundabrufen? –

+1

Welchen Wert geben Sie an den Beendigungshandler zurück? Neue Daten oder keine neuen Daten? Meiner Erfahrung nach wurde es sogar auf iOS8 nicht alle 20-30 Minuten aufgerufen. – Paulw11

Antwort

4

Es stellte sich heraus, dass Hintergrundabrufe in iOS sehr davon abhängen, was Sie innerhalb des Handlers tun, insbesondere Netzwerkaktivität. Hier die Liste von Abhängigkeiten, die Sie prüfen, versuchen sollten, zu verstehen, ob und wie oft iOS führen Sie Ihre holen:

  • Zeit, die Sie in Handler verbringen
  • Ergebnis (NoData, NewData)
  • Fehlerbehandlung (Sie werden gestartet werden weniger wahrscheinlich, wenn Sie Code
  • Timeouts stürzt
  • Stromverbrauch
  • Netzwerkaktivität führen Zusammenhang (Ihre Codeausführung könnte durch iOS unterbrochen werden) (Sie müssen eine Netzwerkanfrage tun, wenn t sagen Hast du NewData, sonst könnte dein Fetch das nächste Mal an einem Tag oder so nie ausgeführt werden.

Apps, die schnell kleine Mengen von Content herunterzuladen und genau reflektieren, wenn sie Inhalte herunterladen hatten zur Verfügung, ist mehr wahrscheinlich Ausführungszeit in der Zukunft als Anwendungen, die eine lange Zeit zum Download erhalten ihr Inhalt oder , dass Inhalt Anspruch war verfügbar , aber dann nichts herunterladen.

Der letzte Punkt stellte sich heraus, in meinem Fall von entscheidender Bedeutung sein, weil zu Testzwecken ich Fetches erklärt und nie versucht, etwas herunterzuladen. Sobald ich begonnen habe, Netzwerk in der Handler zu verwenden, funktionieren Hintergrundabrufe alle 15-30 Minuten wie erwartet.

Apple-docs: https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

Verwandte Themen