检查CLLocationManager的实例是否为isUpdatingLocation

时间:2013-11-22 11:49:55

标签: ios objective-c cllocationmanager

我需要知道CLLocationManager的实例(在本例中称为gps)是否正在更新调用正确方法的位置

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

在我的情况下,完整的方法是:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    //NSLog(@"didUpdateToLocation: %@", newLocation);
    currentLocation = newLocation;

    if (currentLocation != nil) {
        longitude.text = [NSString stringWithFormat:@"%.3f", currentLocation.coordinate.longitude];
        latitude.text = [NSString stringWithFormat:@"%.3f", currentLocation.coordinate.latitude];
    }

    address.text = NULL;
    [activityIndicator setHidden:NO];
    [activityIndicator startAnimating];
    NSLog(@"Resolving the Address");
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
        //NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) {
            placemark = [placemarks lastObject];
            [address sizeToFit];
            address.text = [NSString stringWithFormat:@"%@, %@\n%@ %@\n%@",
                            [self sanitizedDescription:placemark.thoroughfare],
                            [self sanitizedDescription:placemark.subThoroughfare],
                            [self sanitizedDescription:placemark.postalCode],
                            [self sanitizedDescription:placemark.locality],
                            [self sanitizedDescription:placemark.country]];


            if (address.text != NULL)
            {
                gpsTimer = [NSTimer scheduledTimerWithTimeInterval:10
                                                            target:gps
                                                          selector:@selector(startUpdatingLocation)
                                                          userInfo:nil
                                                           repeats:NO];
                [address sizeToFit];
                [gps stopUpdatingLocation];
            }
        } else {
            NSLog(@"%@", error.debugDescription);
        }
    } ];

}

我该怎么办?

提前致谢:)

4 个答案:

答案 0 :(得分:8)

将CLLocationManager子类化,并在调用委托方法时添加一个设置为yes的BOOL ...

您也可以简单地告诉您的位置管理员在委托方法

内停止

答案 1 :(得分:2)

下面是一个简单的示例代码,用于说明如何处理此问题。

import Foundation
import CoreLocation

public class LocationManager : NSObject, CLLocationManagerDelegate{  

    var locationManager: CLLocationManager?
    public var isLocationUpdate: Bool = false


     override public init() {
        super.init()

        self.locationManager = CLLocationManager()
        self.locationManager!.delegate = self

        if #available(iOS 9.0, *) {            
            self.locationManager!.requestWhenInUseAuthorization()          
        }
        self.locationManager!.startUpdatingLocation()
        self.isLocationUpdate = false
    }


public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
   self.isLocationUpdate = true
  print(locations)

}


public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

        //Retrieving the error code.
      if let code = (error as NSError).code{
        isLocationUpdate = false
      }
}

答案 2 :(得分:0)

你真的没办法检查“这个位置管理员的”我的代表是否活跃了吗?“。

您需要做的是跟踪您是否已完成位置更新。

我不确定这是否是你需要的,但这就是我的所作所为:

1-当我开始请求更新时,我会像你一样,即通过requestlocationupdates和一个代表。

2-如果我没有得到我需要的更新,我想在一段时间后超时,以便我的应用程序不会永远等待一个位置,在这种情况下我使用一个选择器超时:

[self performSelector:@selector(fetchLocationTimeout) withObject:nil afterDelay:LOCATION_LISTEN_TIME];

并在选择器中:

(void)fetchLocationTimeout{
    if(!finished){
        [self stopUpdatingLocation];    
        [delegate locationFinished:bestEffortAtLocation];//see more on this below
    }
}

3-在我的didupdate-delegate中我都存储了我所获得的“最佳”位置,如果我确定新位置“足够好”,我就完成了我的位置获取过程:

(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{

    if(newLocation is the best i have){

        self.bestEffortAtLocation = newLocation;

    }
// test the measurement to see if it is more accurate than the previous measurement

    if (bestEffortAtLocation == nil || newLocation is the best i have) {
// store the location as the "best effort"
        if (bestEffortAtLocation is good enough and i want to use it) {        
            [self stopUpdatingLocation];            
        // we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary
        SEL selector = NSSelectorFromString(@"fetchLocationTimeout");
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:selector object:nil];
            [delegate locationFinished:bestEffortAtLocation];
        }
    }
}

最后,这是我在上面调用的方法,从didupdate-delegate和选择器超时中都可以降低竞争条件的风险:

(void)stopUpdatingLocation{
    finished = true;
    NSLog(@"stopUpdatingLocation! manager: %@", [locationManager description]);
    [locationManager stopUpdatingLocation];
    locationManager.delegate = nil;
}

最后的注释:当我完成时,我正在调用的“委托”是我自己的界面,描述了一个知道如何处理位置获取过程结果的类。正如你所看到的,它只有一种方法可以实现“locationFinished”。

希望这有帮助,即使我的代码粘贴技巧不完全是忍者。

答案 3 :(得分:0)

Apple弃用了iOS 6中的一个主要位置管理器委托方法,因此如果您支持旧版本的iOS以及当前版本,则需要支持两种委托方法:

iOS 2 - iOS 5:

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

iOS 6及更高版本:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations