iOS-Hintergrund Ort, an dem keine http-Anfrage gesendet wird
Meine App muss den Standort des Benutzers im Hintergrund verfolgen, kann jedoch keine Abrufanforderung senden. Die http-Anfrage wird sofort gesendet, wenn die App in den Vordergrund tritt. Ich benutze RestKit für alle meine Netzwerkanforderungen und ich folgtedieses Tutorial zum Einrichten meines Hintergrundstandort-Dienstes. In meiner applicationDidEnterBackground
-(void)applicationDidEnterBackground:(UIApplication *)application
{
self.bgLocationManager = [[CLLocationManager alloc] init];
self.bgLocationManager.delegate = self;
[self.bgLocationManager startMonitoringSignificantLocationChanges];
NSLog(@"Entered Background");
}
und ich beendeMonitoringSignificantLocationChange in meinem applicationDidBecomeActive-Delegaten
Dies ist mein locationManager-Delegat, an dem ich den neuen aktualisierten Standort akzeptiere und an meinen Server sende
-(void) locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(@"I am in the background");
bgTask = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:
^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
}];
// ANY CODE WE PUT HERE IS OUR BACKGROUND TASK
NSString *currentLatitude = [[NSString alloc]
initWithFormat:@"%g",
newLocation.coordinate.latitude];
NSString *currentLongitude = [[NSString alloc]
initWithFormat:@"%g",
newLocation.coordinate.longitude];
NSString *webToken = [[NSUserDefaults standardUserDefaults] stringForKey:@"userWebToken"];
NSLog(@"I am in the bgTask, my lat %@", currentLatitude);
NSDictionary *queryParams;
queryParams = [NSDictionary dictionaryWithObjectsAndKeys:webToken, @"auth_token", currentLongitude, @"lng", currentLatitude, @"lat", nil];
RKRequest* request = [[RKClient sharedClient] post:@"/api/locations/background_update" params:queryParams delegate:self];
//default is RKRequestBackgroundPolicyNone
request.backgroundPolicy = RKRequestBackgroundPolicyContinue;
// AFTER ALL THE UPDATES, close the task
if (bgTask != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}
Die Netzwerkanforderungen funktionieren wie geplant, werden jedoch nicht im Hintergrund aufgerufen. Gibt es zusätzliche Schritte, die ich benötige? In meiner info.plist habe ich den Required Background Modes Key und Location-Services als Wert.
BEARBEITEN
Ich habe auch darauf hingewiesenDiese vergangene SO Antwort. Ich habe einige Tests mit dem Einfügen von Protokollen während des Aufrufs von didUpdateToLocation durchgeführt, und sie wurden alle aufgerufen, aber die Anforderung 'get' wurde nicht gesendet. Stattdessen, als ich die App endlich in den Vordergrund starte, schickte sie alle gebauten Netzwerkanforderungen (über 10).
BEARBEITEN (2) Ich habe meiner Anfrage RKRequestBackgroundPolicyContinue hinzugefügt, aber meine Ergebnisse wurden nicht geändert. (Wie du siehstHier im Hintergrund (Upload / Download für Restkit). Ich sehe, dass Restkit den Host initialisiert, aber die Anfrage nicht sendet, bis die App aktiv wird.
ANTWORTEN
RestKit muss etwas tun, das im Hintergrund verboten ist. Die Verwendung einer NSURLRequest funktioniert einwandfrei.
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.example.com/api/locations/background_update"]];
[urlRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[urlRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody:jsonData];
NSHTTPURLResponse *response = nil;
[NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
Es ist in Ordnung, eine synchrone Anforderung zu verwenden, da es keine Benutzeroberfläche gibt, die bei Hintergrundaufgaben unterbrochen werden könnte