Iphone CLLocationManager可能受其他应用程序的影响?

Iphone CLLocationManager可能受其他应用程序的影响?,iphone,ios,cllocationmanager,Iphone,Ios,Cllocationmanager,我遇到了一个非常奇怪的情况,我有一个应用程序,它使用CLLocationManager获取用户的当前位置。我使用的包装器类与Apple的CLLocationManager示例代码非常相似。它开始寻找位置,然后等待,直到给出满足某些条件(时间戳年龄、准确性)的位置。当我在一个GPS很容易到达的区域时,一切都很好 现在是问题。当我在办公室使用WiFi连接时,GPS信号看起来很糟糕,我打开我的应用程序,它永远找不到合适的位置。我退出我的应用程序,打开Foursquare,它几乎立刻就能找到我附近的地方

我遇到了一个非常奇怪的情况,我有一个应用程序,它使用CLLocationManager获取用户的当前位置。我使用的包装器类与Apple的CLLocationManager示例代码非常相似。它开始寻找位置,然后等待,直到给出满足某些条件(时间戳年龄、准确性)的位置。当我在一个GPS很容易到达的区域时,一切都很好

现在是问题。当我在办公室使用WiFi连接时,GPS信号看起来很糟糕,我打开我的应用程序,它永远找不到合适的位置。我退出我的应用程序,打开Foursquare,它几乎立刻就能找到我附近的地方,让我认为它找到了我的位置。我退出Foursquare,重新打开我的应用程序,发现它几乎可以立即找到我的位置

有人能解释一下这里可能发生的事情吗?如果人们认为这会有所帮助,我可以发布一些代码,但这是一个关于其他应用程序如何对CLLocationManager的功能产生积极或消极影响的一般性问题。理想情况下,我很想知道Foursquare到底在做什么才能如此快速地获得一个位置,以及这会如何导致我的应用程序突然也开始获得一个位置

编辑:根据下面的答案,人们似乎经历过跨应用缓存,这很好。然而,这并不能解释为什么Foursquare会得到一个位置,而我的应用程序只有在使用Foursquare之后才能得到它。下面是我的CLLocationManager代码,希望有人能找到一些冒烟的枪:

- (void) lazyInit {
    if (!self.locationManager) {
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
        self.reverseGeocoder = [[WPGeocodingService alloc] initWithDelegate:self];
        self.locationAndPlacemark = NO;
    }
}

- (void) getCurrentLocation {
    [self lazyInit];
    self.recentLocation = nil;
    [self performSelector:@selector(timeoutLocationFetch) withObject:nil afterDelay:kLocationFetchTimeout];
    [self.locationManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    NSLog(@"LocationService:update: <%f,%f> Accuracy: %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude,
          newLocation.horizontalAccuracy);

    // 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 (self.recentLocation == nil || self.recentLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
        // store the location as the "best effort"
        self.recentLocation = 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 <= self.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.locationManager stopUpdatingLocation];
            // we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(timeoutLocationFetch) object:nil];

            if ([self.delegate respondsToSelector:@selector(locationService:didReceiveLocation:)]) {
                [self.delegate locationService:self didReceiveLocation:self.recentLocation];
            }
        }
    }    
}

- (void)locationManager:(CLLocationManager *)manager  didFailWithError:(NSError *)error {
    NSLog(@"LocationService:error: %@", [error description]);
    if ([error code] != kCLErrorLocationUnknown) {
        [self.locationManager stopUpdatingLocation];
        if ([self.delegate respondsToSelector:@selector(locationService:didFailWithError:)]) {
            [self.delegate locationService:self didFailWithError:error];
        }
    }
}

- (void) timeoutLocationFetch {
    NSLog(@"LocationService:timeout");
    [self.locationManager stopUpdatingLocation];
    if (self.recentLocation && [self.delegate respondsToSelector:@selector(locationService:didReceiveLocation:)]) {
        if ([self.delegate respondsToSelector:@selector(locationService:didReceiveLocation:)]) {
            [self.delegate locationService:self didReceiveLocation:self.recentLocation];
        }
    } else {
        NSError* error = [NSError errorWithDomain:@"Location Error" code:0 userInfo:
                          [NSDictionary dictionaryWithObject:@"The application could not determine your location." forKey:NSLocalizedDescriptionKey]];
        if ([self.delegate respondsToSelector:@selector(locationService:didFailWithError:)]) {
            [self.delegate locationService:self didFailWithError:error];
        }
    }
}
-(void)lazyInit{
如果(!self.locationManager){
self.locationManager=[[CLLocationManager alloc]init];
self.locationManager.delegate=self;
self.locationManager.desiredAccuracy=KCallocationAccuracyHundredMeters;
self.reverseGeocoder=[[WPGeocodingService alloc]initWithDelegate:self];
self.locationAndPlacemark=否;
}
}
-(void)getCurrentLocation{
[自我懒散];
self.recentLocation=nil;
[self-performSelector:@selector(timeoutLocationFetch)with object:nil afterDelay:kLocationFetchTimeout];
[self.locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation{
NSLog(@“LocationService:更新:精度:%f”、newLocation.coordinate.latitude、newLocation.coordinate.longitude、,
新定位(水平精度);
//测试位置度量的年龄,以确定度量是否已缓存
//在大多数情况下,您不希望依赖缓存的度量
NSTimeInterval locationAge=-[newLocation.timestamp timeintervalncesInnow];
如果(位置>5.0)返回;
//测试水平精度是否表明测量无效
if(newLocation.horizontalcreaction<0)返回;
//测试测量值,查看其是否比以前的测量值更准确
if(self.recentLocation==nil | | self.recentLocation.HorizontalAccurance>newLocation.HorizontalAccurance){
//将位置存储为“尽最大努力”
self.recentLocation=newLocation;
//测试测量值,看它是否符合要求的精度
//
//重要提示!!!KCLLOCATIONACURACYBEST不应用于与位置坐标或高程进行比较
//准确度,因为它是一个负值。相反,与一些预先确定的“真实”测量值进行比较
//可接受的准确性,或取决于停止更新的超时。此示例取决于超时。
//

如果(newLocation.horizontalAccuracy是的,我认为CLLocationManager在某种程度上缓存了位置,我尝试了一些东西,比如运行谷歌地图,找到了我的位置,然后运行我的应用程序,它立即找到了我的位置。此外,运行导航应用程序,找到了我的位置,立即杀死它,运行其他使用位置的应用程序,所有应用程序都可以几乎可以在瞬间找到该位置的锁。

为什么要使用

self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
而不是
KCLLOCATIONACURACYBEST
?当然,没有将水平精度与此进行比较,正如您自己所注意到的,是负常数-而是一些合理的其他值(比如100.0m)。您是否尝试过它是否会产生差异

所需的精度控制在位置获取上投入的精力(对于较高的值,GPS甚至没有打开,您可以使用Xcode/Instruments/EnergyDiagnostics进行检查)。较少的精力会导致获得位置的精度降低和/或时间延长。这听起来不合理吗

根据我自己的观察:当要求iOS提供某个所需精度的位置时,结果可能是:精度较低(即在GPS接收较差的建筑物中),与所需精度相同,或者事实上比所需精度更高(同一应用程序的另一个应用程序或另一个CLlocationManager对象可能同时要求硬件提供更高的精度-然后所有其他应用程序无需额外努力即可继承更好的值)

除上述内容外,您的iOS设备是否正在访问互联网可能会有所不同,因为它是一个辅助GPS接收器。如果设备由于其他互联网活动而在线,下载一些辅助数据可能会产生某种副作用。thoug说,最后一种想法纯粹是猜测h

还有一件事: 如果我没有在代码中忽略它,那么您还没有定义距离过滤器

self.locationManager.distanceFilter = kCLDistanceFilterNone;

确保您获得尽可能多的更新。

我们中的许多人都想知道同样的事情……关于缓存,或者关于Foursquare是如何收集位置坐标的?我看到了一些有趣的行为:在启动时收集位置,这与(例如)谷歌地图不符。然而他们(似乎)立即获取信息,我的应用程序不可用