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

Antworten auf die Frage(3)

Ihre Antwort auf die Frage