Ho un'app che ruota attorno al GPS del dispositivo e alle informazioni che ne derivano. È importante che i dati sulla posizione siano accurati e aggiornati. So che il dispositivo è limitato dal suo GPS e dai limiti del GPS, ma mi chiedevo se c'è qualcosa che posso fare per migliorare/migliorare le prestazioni del GPS di iPhone, in particolare nell'area della velocità. Poiché gli aggiornamenti di posizione sono in ritardo di circa 3-5 secondi rispetto alla posizione in tempo reale del dispositivo, anche la velocità rilevata dal gestore di località è troppo indietro rispetto al valore in tempo reale. Nel mio caso, è semplicemente troppo lungo. Capisco che potrebbe non esserci nulla che io possa fare, ma qualcuno ha avuto qualche successo nel migliorare la reattività del GPS dell'iPhone? Ogni piccola cosa fa la differenza.Responsività di CLLocationManager
Edit 1:
mia location manager è all'interno di una classe Singleton, come Apple consiglia.
Interno 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];
All'interno MapView.m (in cui il gestore di posizione viene effettivamente utilizzata):
- (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
}
Il trattamento dei dati avviene all'interno locationManager:didUpdateToLocation:fromLocation:
. Non credo che l'inefficienza qui sia la causa del ritardo.
locationManager:didUpdateToLocation:fromLocation:
chiama questo metodo per aggiornare l'interfaccia utente:
- (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];
}
Con un paio di NSDates e NSLogs ho trovato che l'esecuzione dell'intero (non solo il metodo di aggiornamento etichetta) locationManager:didUpdateToLocation:fromLocation:
non richiede più di circa 8ms sul mio iPhone 4; in altre parole, la gestione dei dati non è il problema.
Mostraci come ottenere i dati sulla posizione. Questo ritardo non è normale. – sosborn
Codice aggiunto. Posso postare di più se necessario. –
3-5 secondi potrebbero essere un po 'esagerati; è tardi e la gamma 3-5 mi è venuta in mente per qualche motivo. Domani eseguirò alcuni test per ottenere numeri esatti. –