CoreLocations reverseGeocodeLocation使其每分钟运行/循环一次

时间:2014-12-17 10:46:57

标签: ios objective-c loops core-location

Hiall我正在使用Corelocation并将基本的long,lat等更新为每秒钟的时间,这是我想要的,但我现在已经引入了reverseGeocodeLocation,我只希望它能够运行/地理编码该位置一次每分钟。目前它也在尽可能地更新,Apple说这是坏的,只希望它每分钟更新一次。

有人可以告诉我这是怎么做到的吗? (保持我的主要重置更新尽可能多,但让我的reverseGeocodeLocation每分钟运行一次。)

我尝试了多种不同的方法来限制reverseGeocodeLocation的运行状态,如果语句和dispatch_after没有成功,我尝试过的其他方法如下,我不确定是否需要执行类似暂停代码的操作不知怎的,虽然它做了地理编码或???我的位置代码是相当股票标准的Apple示例代码。 任何帮助都会很棒!

//以下代码未显示所有代码,但相关部分等

.h
@interface ViewController : UIViewController <CLLocationManagerDelegate>
//I set other standard property outlets for location, locationManager, labels etc
@property (nonatomic, strong) NSDate *reverseGeoLastUpdate; //my 60second reversegeoupdates

.m
@implementation ViewController {
NSTimer *timer;
}

- (void)viewDidLoad {
[super viewDidLoad];
[self startStandardUpdates];
}

- (void)startStandardUpdates {
if (nil == _locationManager)
_locationManager = [[CLLocationManager alloc] init];
geocoder = [[CLGeocoder alloc] init];
_locationManager.delegate = self;
_locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[_locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
CLLocation* location = [locations lastObject];

NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
NSLog(@"eventDate timeIntervalSinceNow = %f", [eventDate timeIntervalSinceNow]);
if (abs(howRecent) < 15.0) {
self.coordinateLat.text = [NSString stringWithFormat:@"%f", location.coordinate.latitude]; 

//我的reverseGeocodeLocation的定时器代码,尝试在开始时运行一次,然后每隔60秒运行一次 //这会在开始时触发一次,因为self.reverseGeoLastUpdate == nil没有错误,但我的屏幕标签上的视图实际上从未使用来自地理服务器的数据进行更新,并且当[self.reverseGeoLastUpdate timeIntervalSinceNow]&gt;时,循环也不会重​​复。 60个???????

if( [self.reverseGeoLastUpdate timeIntervalSinceNow] > 60 || self.reverseGeoLastUpdate == nil ){

NSLog(@"Resolving the Address: Loop run %d", _amountofruns++);
[geocoder reverseGeocodeLocation:_location completionHandler:^(NSArray *placemarks, NSError *error) {
    NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
    if (error == nil && [placemarks count] > 0) {
        placemark = [placemarks lastObject];
        _address1.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@\n",
                          placemark.subThoroughfare, placemark.thoroughfare,
                        //other 4 place marker calls here
                          ];
    } else {
        NSLog(@"%@", error.debugDescription);
    }
}];

self.reverseGeoLastUpdate = [NSDate date];
}
}

当我尝试使用NSTimer取代上面方法中“// my timer”代码的位置但是

“Error Domain = kCLErrorDomain Code = 8”无法完成操作“。

NSTimer scheduledTimerWithTimeInterval: 60.0
                             target: self
                           selector:@selector(onTick:)
                           userInfo: nil
                            repeats:YES];

-(void)onTick:(NSTimer *)timer {
[geocoder reverseGeocodeLocation:_location completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
if (error == nil && [placemarks count] > 0) {
    placemark = [placemarks lastObject];
    _address1.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@\n",
                      placemark.subThoroughfare, placemark.thoroughfare,
                        //other 4 place marker calls here

                      ];
} else {
    NSLog(@"%@", error.debugDescription);
}
}];

当我尝试的时候 dispatch_after方式它会触发并且标签得到更新但是一旦它触发它就会持续触发每一帧,并且无法解决如何每60秒运行一次。

double delayInSeconds = 60.0;
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(delayTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),
           ^(void){

[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
if (error == nil && [placemarks count] > 0) {
    placemark = [placemarks lastObject];
    _address1.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@\n",
                        placemark.subThoroughfare, placemark.thoroughfare,
                        //other 4 placemarks
                        ];
} else {
    NSLog(@"%@", error.debugDescription);
}
}];

});

任何有关如何正确执行此操作的帮助都会很棒

1 个答案:

答案 0 :(得分:1)

您的第一个代码几乎是正确的,但您需要考虑反向地理编码将在后台线程上完成的事实,并且您应该只更新主队列上的UI。

if(self.reverseGeoLastUpdate == nil || [self.reverseGeoLastUpdate timeIntervalSinceNow] > 59 ) {
    self.reverseGeoLastUpdate = [NSDate date];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) {
            placemark = [placemarks lastObject];
            dispatch_async(dispatch_get_main_queue(), ^{
                self.address1.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@\n",
                          placemark.subThoroughfare, placemark.thoroughfare,
                        //other 4 place marker calls here
                          ];
               });
        } else {
            NSLog(@"%@", error.debugDescription);
        }

    }];
    }
}

此外,尝试养成使用_而不是self访问属性的习惯,除非您故意绕过setter / getter