我遇到了一個非常奇怪的情況,我有一個使用CLLocationManager獲取用戶當前位置的應用程序。我正在使用與Apple的CLLocationManager示例代碼非常相似的包裝類。它開始尋找位置,並等待它獲得符合某些標準的位置(時間戳記年齡,準確性)。當我在一個非常全球定位系統的地區時,所有的工作都很好。CLLocationManager可能受其他應用程序影響嗎?
現在的問題。當我在我的辦公室時,在GPS信號看起來很糟糕的WiFi連接上,我打開我的應用程序,它永遠找不到合適的位置。我退出應用程序,打開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];
}
}
}
我們很多人都想知道同樣的事情..... – KevinDTimm
在緩存方面,或者Foursquare如何收集位置座標? – nickbona
我已經看到了一些有趣的行爲:在啓動時收集不與(例如)谷歌地圖嬉戲的地點。雖然他們(似乎)立即獲取信息,但我的應用程序似乎並未儘快獲取位置更新。在我的應用程序之前運行地圖(例如)提高了我的應用程序的性能:(這看起來不正確 – KevinDTimm