2010-10-16 3 views
6

Ich möchte meine App im Hintergrund mit Standortdiensten weiterlaufen. Dazu habe ich verwendet:App kontinuierlich im Hintergrund laufen zu lassen

-(void)applicationDidEnterBackground:(UIApplication *)application { 

    [locationManager stopUpdatingLocation]; 
    [locationManager startUpdatingLocation]; 

    //timer=[NSTimer scheduledTimerWithTimeInterval:300 target:self selector:@selector(UpdateLocation) userInfo:nil repeats:YES]; 

} 

aber wenn ich NSTimer es nicht verwenden UpdateLocation nicht nennen. Ich habe versucht, es mit einer anderen Methode anzurufen, aber dann hat es auch nur einmal angerufen.

Ich möchte die App kontinuierlich im Hintergrund laufen, Standorte nach regelmäßigen Zeitintervallen erkennen.

Antwort

5

Ich habe dies in einer Anwendung, die ich entwickle. Die Timer funktionieren nicht, wenn sich die App im Hintergrund befindet, die App jedoch ständig die Standortaktualisierungen empfängt. Ich habe irgendwo in der Dokumentation gelesen (ich kann es anscheinend nicht finden, ich poste ein Update, wenn ich das tue), dass eine Methode nur auf einer aktiven Laufschleife aufgerufen werden kann, wenn die App im Hintergrund ist. Der App-Delegat hat sogar im bg eine aktive Laufschleife, so dass Sie keine eigenen erstellen müssen, damit dies funktioniert. [Ich bin nicht sicher, ob dies die richtige Erklärung ist, aber das ist, wie ich aus dem, was ich gelesen habe verstanden habe]

Zuerst fügen Sie das Objekt 'Location' für den Schlüssel 'Hintergrundmodi' in der Datei info.plist Ihrer App hinzu. Nun, was Sie tun müssen, ist die Lage Updates überall in Ihrer Anwendung starten:

CLLocationManager locationManager = [[CLLocationManager alloc] init]; 

locationManager.delegate = self;//or whatever class you have for managing location 

[locationManager startUpdatingLocation]; 

Als nächstes schreiben ein Verfahren mit den Standortaktualisierungen zu handhaben, sagen - (void) didUpdateToLocation: (CLLocation *) Lage, in der App-Delegierte Implementieren Sie dann die Methode locationManager: didUpdateLocation: fromLocation von CLLocationManagerDelegate in der Klasse, in der Sie den Standortmanager gestartet haben (da wir den Standortmanagerdelegaten auf 'self' festgelegt haben). Innerhalb dieser Methode müssen Sie überprüfen, ob das Zeitintervall, nach dem Sie die Standortaktualisierungen verarbeiten müssen, abgelaufen ist. Sie können dies tun, indem Sie jedes Mal die aktuelle Uhrzeit speichern. Wenn diese Zeit abgelaufen ist, rufen Sie die Methode UpdateLocation von AppDelegate:

NSDate *newLocationTimestamp = newLocation.timestamp; 
NSDate *lastLocationUpdateTiemstamp; 

int locationUpdateInterval = 300;//5 mins 

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
if (userDefaults) { 

     lastLocationUpdateTiemstamp = [userDefaults objectForKey:kLastLocationUpdateTimestamp]; 

     if (!([newLocationTimestamp timeIntervalSinceDate:lastLocationUpdateTiemstamp] < locationUpdateInterval)) { 
      //NSLog(@"New Location: %@", newLocation); 
      [(AppDelegate*)[UIApplication sharedApplication].delegate didUpdateToLocation:newLocation]; 
      [userDefaults setObject:newLocationTimestamp forKey:kLastLocationUpdateTimestamp]; 
     } 
    } 
} 

Dies ruft Ihre Methode alle 5 Minuten, auch wenn die App im Hintergrund ist. Imp: Diese Implementierung leert die Batterie, wenn Ihre Standortdaten die Genauigkeit nicht kritisch ist, sollten Sie verwenden [Location startMonitoringSignificantLocationChanges]

Vor dem Hinzufügen dieser zu Ihrer Anwendung finden Sie in der Location Awareness Programming Guide bei http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/Introduction/Introduction.html

+0

Wenn ich mich nicht irre, wird didUpdateToLocation nur alle 5 Minuten aufgerufen, wenn didUpdateLocation in regelmäßigen kleinen Intervallen aufgerufen wird. Wenn Sie startMonitoringSignificantChanges auswählen und sich nicht viel bewegen, erhalten Sie keine Updates in einem Intervall von 5 Minuten. Richtig? – Lolo

0

ich gelesen Ich weiß, das ist sehr spät für eine Antwort. Aber wenn du immer noch keine Antwort hast, hier ist was ich getan habe und meine App läuft ständig im Hintergrund.

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
    UIApplication *app = [UIApplication sharedApplication]; 
    UIBackgroundTaskIdentifier bgTask = 0; 

    backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(backgroundTask) userInfo:nil repeats:YES]; 

    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
     [app endBackgroundTask:bgTask]; 
    }]; 
} 

Jetzt tun, was Sie in der Methode Background wollen.

+0

Ist das in der AppDelegate oder kann das in irgendeiner Klasse sein? – anthoprotic

+0

Ja, dieser Code ist in AppDelegate. Und ich habe es nicht selbst ausprobiert, aber es sollte auch in jeder anderen Klasse funktionieren ... –

+0

Es muss etwas geben, was ich nicht verstehe, denn wenn ich diesen Code einfüge und die Methode backgroundTask leer lasse, läuft meine App im Hintergrund. Wenn ich deinen Code entferne, ist es nicht mehr. – anthoprotic

0

Sie können zum Ausführen von App im Hintergrund für bestimmte Aufgabe verwenden.

+0

Dies scheint die exakt gleiche Lösung zu sein, die @ Vish_Obj-C zuvor gepostet hat. Was vermisse ich? – smholloway

+0

Code sieht falsch aus. Der Block wird den Wert von "bgTask" beim Erstellen erfassen, was 0 ist, was zu einem falschen '[app endBackgroundTask: 0]' führt. Stattdessen möchten Sie wahrscheinlich eine Ivar/property bgTaskID haben, damit die Zuweisung an den Block weitergegeben werden kann. –