【问题标题】:CoreLocations reverseGeocodeLocation getting it to run / loop once per minute onlyCoreLocations reverseGeocodeLocation 让它每分钟运行/循环一次
【发布时间】:2014-12-17 10:46:56
【问题描述】:

Hiall我正在使用 Corelocation 并将基本的经纬度等更新为每秒尽可能多的视图,这就是我想要的,但我现在引入了 reverseGeocodeLocation,我只希望它运行/地理编码一次位置每分钟。目前它也在尽可能多地更新,Apple 认为这是不好的,并且只希望它每分钟更新一次。

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

我尝试了多种不同的方法来限制reverseGeocodeLocation runlike 与计时器的数量,如果语句和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] > 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 代替上述方法中的“//我的计时器”代码但得到

"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);
}
}];

});

任何有助于弄清楚如何正确执行此操作的帮助都会很棒

【问题讨论】:

    标签: ios objective-c loops core-location


    【解决方案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

    【讨论】:

    • 嗨 Paulw11 感谢您的回复,是的,我还没有深入研究让事情在不同的线程上运行。当我执行您的代码时(我添加了调试 4 timeInterval),我现在得到 2014-12-18 12:28:16.028 myapp[16858:10068748] self.reverseGeoLastUpdate timeIntervalSinceNow 0.000000 2014-12-18 12:28:16.207 myapp[16858: 10068748] 找到地标:(null),错误:错误域 = kCLErrorDomain 代码 = 8“操作无法完成。(kCLErrorDomain 错误 8。)”2014-12-18 12:28:16.207 myapp[16858:10068748] Error Domain=kCLErrorDomain Code=8 "操作无法完成。(kCLErrorDomain error 8.)" ?
    • 您也可以告诉我调试控制台输出中的 [16858:10068748] 是什么意思?
    • 我不知道这些数字是什么意思。我认为这与进程 ID 和日期/时间有关。错误 8 的原因是因为您尝试反向地理编码的位置为零。在您的原始代码中,您使用_location,我将其更改为self.location,但您上面的代码没有设置self.location/_location,它设置了局部变量location。我已更新我的答案以删除 self.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 2019-06-09
    • 2015-03-27
    • 1970-01-01
    相关资源
    最近更新 更多