1

オフィス用のカスタム アプリケーションを作成しています。このアプリで 5 分ごと (またはその程度) にユーザーの位置情報を取得し、json 経由でサーバーに送信する必要があります。動作していますが、バックグラウンドで10分以上実行されません(わかります)。

必要なバックグラウンド モードに「位置情報更新のためのアプリ登録」を追加しました。

私のコードは、次のように AppDelegate にあります。

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

NSLog(@"Became active");

// Start location services
locationManager = [[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = 100.0f;
locationManager.delegate = self;

[locationManager stopMonitoringSignificantLocationChanges];
[locationManager startUpdatingLocation];

}


- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{


BOOL isInBackground = NO;
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
{
    isInBackground = YES;

}
NSLog(@"Location Manager isInBackground: %hhd", isInBackground);

if (isInBackground)
{
    [self sendBackgroundLocationToServer:newLocation];
}
else
{
    [self sendDataToServer:newLocation];
}

}


-(void) sendBackgroundLocationToServer:(CLLocation *)location
{

bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    [[UIApplication sharedApplication] endBackgroundTask:bgTask];
}];

// Send the data
[self sendDataToServer:location];

if (bgTask != UIBackgroundTaskInvalid)
{
    [[UIApplication sharedApplication] endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}
}

-(void) sendDataToServer:(CLLocation *)newLocation
{
NSLog(@"Sending Data to Server");
// Get battery level
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
float batteryLevel = [[UIDevice currentDevice] batteryLevel];

float lat = newLocation.coordinate.latitude;
float lng = newLocation.coordinate.longitude;
NSLog(@"Accuracy: %f", newLocation.horizontalAccuracy);
NSString *userId = [[NSUserDefaults standardUserDefaults] stringForKey:@"userId"];
NSString *post = [[NSString alloc] initWithFormat:@"login_id=%@&latitude=%f&longitude=%f&speed=%f&course=%f&battery_level=%f&horizontal_accuracy=%f&vertical_accuracy=%f",
                  userId,
                  lat,
                  lng,
                  [newLocation speed],
                  [newLocation course],
                  batteryLevel,
                  newLocation.horizontalAccuracy,
                  newLocation.verticalAccuracy];

NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];

NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSString *urlstring = [NSString stringWithFormat:@"%@webservice/post_logins_location.php", kBaseURL];
[request setURL:[NSURL URLWithString:urlstring]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];

NSError *error;
NSURLResponse *response;
NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
jsonResults = [NSJSONSerialization JSONObjectWithData:urlData options:kNilOptions error:&error];
NSLog(@"GPS Send results: %@", jsonResults);

_lastSentUpdateAt = [NSDate date];
}

また、startMonitoringSignificantLocationChanges を使用して _lastSentUpdateAt を完全に削除してみました。しかし、私はまだ同じ結果を得ています。私の質問は、json が 10 分後にバックグラウンドからデータを送信できるかどうかです。現在、私の電話は 1 時間以上稼働しており、位置情報サービスのアイコンはまだアプリでアクティブになっています。ただし、更新でサーバーにデータがヒットすることはありません。実際にアプリを開くと、バックグラウンドでのデータ送信に問題があると思わせる更新を受け取りました。それとも何か他のことが起こっていますか?

4

1 に答える 1

2

ドキュメンテーションを読み、「重要な位置情報更新への登録」に関連する WWDC プレゼンテーションをご覧ください。彼らは、電力消費を慎重にしながら、公式に推奨されている方法を改善および変更しました。

具体的には、指定した時間間隔でバックグラウンドの場所を取得する方法はありません。重要な位置情報更新は OS の裁量で発生し、アプリの制御を超えた多くの要因の影響を受けます。

アプリがバックグラウンドで終了しないようにするだけの場合は、アプリの plist でそのようなバックグラウンド モードを宣言する必要があります。Xcodeの「情報」の下、「アプリは位置情報の更新を登録します」の下にあると思います。

于 2013-09-17T18:11:57.477 に答える