CLLocationManager réactivité

J'ai une application qui tourne autour de l'appareil GPS et les informations qui en découle. Il est important que l'emplacement des données exactes et à jour. Je sais que l'appareil est limité par son GPS et le GPS est limite, mais je me demandais si il n'y a rien que je peux faire pour modifier/améliorer les performances du GPS de l'iPhone, en particulier dans la zone vitesse. Parce que l'emplacement des mises à jour de décalage d'environ 3 à 5 secondes derrière la localisation en temps réel de l'appareil, la vitesse signalée par le directeur des lieux est aussi à la traîne loin derrière la valeur en temps réel. Dans mon cas, qui est tout simplement trop long. Je comprends qu'il y a peut-être pas quelque chose que je peux faire, mais personne n'a jamais eu de succès dans l'amélioration de la réactivité du GPS de l'iPhone? Chaque petit geste fait une différence.

Edit 1:

Ma position manager est à l'intérieur d'une classe singleton, Apple recommande.

À L'Intérieur De SingletonDataController.m:

static CLLocationManager* locationManager;
locationManager = [CLLocationManager new];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.headingFilter = kCLHeadingFilterNone;

if(([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging) || ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull)) {
    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
} else {
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}

[sharedSingleton setLocationManager:locationManager];
[locationManager release];

À L'Intérieur De MapView.m (où l'emplacement manager est en cours d'utilisation):

- (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil {
    //setup
    [SingletonDataController sharedSingleton].locationManager.delegate = self;
    //more setup
}

- (void)batteryChanged {
    if(([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging) || ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull)) {
        [SingletonDataController sharedSingleton].locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    } else {
        [SingletonDataController sharedSingleton].locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    }
}

- (void)viewDidLoad {
    //setup
    [[NSNotificationCenter defaultCenter]
      addObserver:self 
         selector:@selector(batteryChanged) 
             name:UIDeviceBatteryStateDidChangeNotification 
           object:nil];
    //other setup
}

Le traitement des données se fait à l'intérieur locationManager:didUpdateToLocation:fromLocation:. Je ne crois pas que l'inefficacité est ici la cause du lag.

locationManager:didUpdateToLocation:fromLocation: appelle cette méthode pour mettre à jour l'INTERFACE utilisateur:

- (void)setLabels:(CLLocation*)newLocation fromOldLocation:(CLLocation*)oldLocation {
//set speed label
if(iterations > 0) {
if(currentSpeed > keyStopSpeedFilter) {
if(isFollowing) {
[mapViewGlobal setRegion:MKCoordinateRegionMake([newLocation coordinate], mapViewGlobal.region.span)];
}
NSString* currentSpeedString;
if(isCustomary) {
currentSpeedString = [[NSString alloc] initWithFormat:@"%.1f miles per hour", (currentSpeed * 2.23693629f)];
} else {
currentSpeedString = [[NSString alloc] initWithFormat:@"%.1f km per hour", (currentSpeed * 3.6f)];
}
[speedLabel setText:currentSpeedString];
[currentSpeedString release];
} else {
speedLabel.text = @"Not moving";
}
}
//set average speed label
if(iterations > 4 && movementIterations > 2) {
NSString* averageSpeedString;
if(isCustomary) {
averageSpeedString = [[NSString alloc] initWithFormat:@"%.1f miles per hour", (float)((speedAverages / (long double)movementIterations) * 2.23693629f)];
} else {
averageSpeedString = [[NSString alloc] initWithFormat:@"%.1f km per hour", (float)((speedAverages / (long double)movementIterations) * 3.6f)];
}
[averageSpeedLabel setText:averageSpeedString];
[averageSpeedString release];
}
//set elapsed time label
NSInteger seconds = [[NSDate date] timeIntervalSinceDate:dataObject.locationManagerStartDate];
NSInteger minutes = seconds / 60;
NSInteger hours = minutes / 60;
//get remainder
seconds %= 60;
NSString* timeString;
NSString* secondsString;
NSString* minutesString;
NSString* hoursString;
if((seconds % 60) < 10) {
secondsString = [[NSString alloc] initWithFormat:@"0%i", seconds];
} else {
secondsString = [[NSString alloc] initWithFormat:@"%i", seconds];
}
if((minutes % 60) < 10) {
minutesString = [[NSString alloc] initWithFormat:@"0%i", minutes];
} else {
minutesString = [[NSString alloc] initWithFormat:@"%i", minutes];
}
if((hours % 60) < 10) {
hoursString = [[NSString alloc] initWithFormat:@"0%i", hours];
} else {
hoursString = [[NSString alloc] initWithFormat:@"%i", hours];
}
timeString = [[NSString alloc] initWithFormat:@"%@:%@:%@", hoursString, minutesString, secondsString];
[elapsedTimeLabel setText:timeString];
[timeString release], timeString = nil;
[secondsString release], secondsString = nil;
[minutesString release], minutesString = nil;
[hoursString release], hoursString = nil;
NSString* totalDistanceString;
if(isCustomary) {
totalDistanceString = [[NSString alloc] initWithFormat:@"Total: %.2f mi", (float)distance * 0.000621371192f];
} else {
totalDistanceString = [[NSString alloc] initWithFormat:@"Total: %.2f km", (float)distance / 1000.0f];
}
[customTopBar setTitle:totalDistanceString];
[totalDistanceString release];
}

Avec un couple de NSDates et NSLogs j'ai trouvé que l'exécution de l'ensemble locationManager:didUpdateToLocation:fromLocation: (pas juste l'étiquette méthode de mise à jour) ne prend jamais plus de sujet de 8ms sur mon iPhone 4; en d'autres termes, le traitement des données n'est pas le problème.

Montrez-nous comment vous avez trouvé l'emplacement des données. Ce décalage n'est pas normal.
Ajout d'un code. Je peux poster la suite si nécessaire.
3-5 secondes peut-être un peu exagéré; il est tard et de la plage de 3-5 juste sauté dans ma tête pour une raison quelconque. Demain, je vais faire quelques tests pour obtenir des chiffres exacts.
Rien d'étrange là. Que faites-vous dans locationManager:didUpdateToLocation:fromLocation: et comment êtes-vous déterminer que c'est à la traîne?
Désolé je ne peux pas aider avec le problème de latence. Mais je pense que vous pouvez simplifier l'initialisation de secondsString/minutesString/hoursString acheter à l'aide d'un @"%02i" pour formater automatiquement le nombre avec un 0 sans explicitement test pour "<10"

OriginalL'auteur eric.mitchell | 2012-03-17