我的程序通过GPS加载用户的当前位置并将其保存在txt文件中以通过电子邮件发送以用于统计目的。我的问题是:
首次尝试使用以下方式每次保存位置时延迟15秒
[NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(locationManager:) userInfo:nil repeats:YES];
问题是这不起作用,不知道是什么原因。
代码:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
//Obtenemos las coordenadas.
latitud = newLocation.coordinate.latitude;
longitud = newLocation.coordinate.longitude;
precision = newLocation.horizontalAccuracy;
// Lo mostramos en las etiquetas
[latitudLabel setText:[NSString stringWithFormat:@"%0.8f",latitud]];
[longitudLabel setText:[NSString stringWithFormat:@"%0.8f",longitud]];
[precisionLabel setText:[NSString stringWithFormat:@"%0.8f",precision]];
tiempoLabel=[self.dateFormatter stringFromDate:newLocation.timestamp];
//NSLog(@"tiempo: %@",tiempoLabel);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"textfile.txt"];
//[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
// create if needed
if (![[NSFileManager defaultManager] fileExistsAtPath:path]){
[[NSData data] writeToFile:path atomically:YES];}
NSString *contents = [NSString stringWithFormat:@"tiempo: %@ latitude:%+.6f longitude: %+.6f precisión: %f\n",tiempoLabel,latitud,longitud,precision];
NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:path];
[handle truncateFileAtOffset:[handle seekToEndOfFile]];
[handle writeData:[contents dataUsingEncoding:NSUTF8StringEncoding]];}
感谢您的帮助。 StackOverflow对我的项目帮助很大
答案 0 :(得分:1)
您提出了两个不同的问题:
关于您的计时器,您有一个名为locationManager:
的方法吗?你还没有展示出这种方法,所以它看起来非常可疑。如果您尝试拨打locationManager:didUpdateToLocation:fromLocation:
,那将无效。 @selector
的{{1}}必须不超过一个参数。您可以编写一个简单的计时器处理程序方法来调用您想要的任何方法,例如。
NSTimer
然后你可以这样做:
- (void)handleTimer:(NSTimer *)timer
{
// call whatever method you want here
}
注意,重复计时器可能会导致保留周期,因此如果您计划在某个时候解除此计时,您可能希望保留对计时器的引用,以便稍后[NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES];
可以引用它(例如在{{ 1}})。
话虽如此,我同意律师不要每15秒写一次,而是使用desiredAccuracy
和distanceFilter
来控制何时调用位置管理器委托方法。每隔 x 秒记录位置是粉碎用户电池的好方法。有关其他节电指南,请参阅位置感知编程指南中的Tips for Conserving Battery。
关于你的第二个问题,
您无需执行“根据需要创建”代码;以及
在编写文件时,您不需要invalidate
代码;您可以使用viewDidDisappear
实例方法writeToFile:atomically:encoding:error:
(顺便提一下,它包含一个NSFileHandle
参数,您可以检查文件写入是否成功)。
答案 1 :(得分:0)
你可能想放弃计时器并检查一定的准确度,这里有一些检查gps准确度的示例代码,需要修改或根据你的需要从中取一两行
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// test the age of the location measurement to determine if the measurement is cached
// in most cases you will not want to rely on cached measurements
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;
// test the measurement to see if it is more accurate than the previous measurement
if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
// store the location as the "best effort"
self.bestEffortAtLocation = newLocation;
// test the measurement to see if it meets the desired accuracy
//
// IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue
// accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of
// acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout.
//
if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
// we have a measurement that meets our requirements, so we can stop updating the location
//
// IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible.
//
[self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")];
// we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];
}
}
}
至于日期与命名问题混淆的文件我会假设标题的数字格式可以很好地满足您的需求。虽然看看你的代码,你需要分离你的didUpdateLocation发生的很多事情方法,因为这将平均每隔几秒调用一次,这会产生很多问题,而不会告诉程序等待或直到某个点再次更新文件。