我已經知道如何使用CLLocationManager,所以我可以用困難的方式來完成,包括委託和所有這些。獲取iPhone當前位置的最簡單方法是什麼?
但我想有一個方便的方法,僅僅獲得當前位置,一次,阻塞,直到它得到的結果。
我已經知道如何使用CLLocationManager,所以我可以用困難的方式來完成,包括委託和所有這些。獲取iPhone當前位置的最簡單方法是什麼?
但我想有一個方便的方法,僅僅獲得當前位置,一次,阻塞,直到它得到的結果。
有沒有「方便的方法」除非你自己編寫它們,但你仍然需要實現在任何自定義代碼,你用它來把事情委託方法「方便」。
的委託模式是有原因的,並作爲代表是Objective-C的重要組成部分,我建議你與他們舒服。
我所做的是實現一個單例類來管理來自核心位置的更新。要訪問我的當前位置,我做了CLLocation *myLocation = [[LocationManager sharedInstance] currentLocation];
如果你想阻止主線程你可以做這樣的事情:
while ([[LocationManager sharedInstance] locationKnown] == NO){
//blocking here
//do stuff here, dont forget to have some kind of timeout to get out of this blocked //state
}
但是,因爲它已經被指出的那樣,阻止主線程可能不是一個好主意,但這可能是一個很好的起點,因爲你正在建造一些東西。您還會注意到,我寫的類檢查位置更新的時間戳,並忽略任何舊時間戳,以防止從核心位置獲取陳舊數據的問題。
這是我寫的單身人士課程。請注意,這是有點粗糙的邊緣:
#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>
@interface LocationController : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
CLLocation *currentLocation;
}
+ (LocationController *)sharedInstance;
-(void) start;
-(void) stop;
-(BOOL) locationKnown;
@property (nonatomic, retain) CLLocation *currentLocation;
@end
@implementation LocationController
@synthesize currentLocation;
static LocationController *sharedInstance;
+ (LocationController *)sharedInstance {
@synchronized(self) {
if (!sharedInstance)
sharedInstance=[[LocationController alloc] init];
}
return sharedInstance;
}
+(id)alloc {
@synchronized(self) {
NSAssert(sharedInstance == nil, @"Attempted to allocate a second instance of a singleton LocationController.");
sharedInstance = [super alloc];
}
return sharedInstance;
}
-(id) init {
if (self = [super init]) {
self.currentLocation = [[CLLocation alloc] init];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[self start];
}
return self;
}
-(void) start {
[locationManager startUpdatingLocation];
}
-(void) stop {
[locationManager stopUpdatingLocation];
}
-(BOOL) locationKnown {
if (round(currentLocation.speed) == -1) return NO; else return YES;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
//if the time interval returned from core location is more than two minutes we ignore it because it might be from an old session
if (abs([newLocation.timestamp timeIntervalSinceDate: [NSDate date]]) < 120) {
self.currentLocation = newLocation;
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertView *alert;
alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[error description] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
-(void) dealloc {
[locationManager release];
[currentLocation release];
[super dealloc];
}
@end
感謝您的解決方案。這是一個很好的小控制器。我發現的一件事是,locationKnown方法不是很準確 - 它總是返回YES,因爲currentLocation在init方法中初始化。以下是使用speed屬性確定用戶位置是否已被接收的方法的替代版本: - (BOOL)locationKnown if(round(currentLocation.speed)== -1) return NO; else return YES; } – 2010-08-13 00:25:21
有沒有這樣的便利,你不應該創建自己的。 「阻塞直到得到結果」爲極其糟糕在像iPhone這樣的設備上進行編程練習。檢索一個位置可能需要幾秒鐘的時間;你永遠不應該讓你的用戶這樣等待,而且代表確保他們不這樣做。
我讚賞布拉德史密斯的答案。實現它我發現他採用的方法之一是從iOS6開始已棄用。編寫代碼,既要對付的iOS5和iOS6的工作,使用以下命令:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
if (abs([[locations lastObject] timeIntervalSinceDate:[NSDate date]]) < 120) {
[self setCurrentLocation:[locations lastObject]];
}
}
// Backward compatibility with iOS5.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSArray *locations = [NSArray arrayWithObjects:oldLocation, newLocation, nil];
[self locationManager:manager didUpdateLocations:locations];
}
我簡化和合並多個答案的地方,如果它是有效的位置,纔會更新。
它也適用於OSX以及iOS。
這裏假定當前位置突然被用戶所需的用例。如果在這個例子中超過100毫秒,它被認爲是一個錯誤。 (假設GPS IC & |無線上網(蘋果公司的天棚克隆)已經被解僱了,並具有良好的修復了。)
#import "LocationManager.h"
// wait up to 100 ms
CLLocation *location = [LocationManager currentLocationByWaitingUpToMilliseconds:100];
if (!location) {
NSLog(@"no location :(");
return;
}
// location is good, yay
你應該澄清一個問題:如果你知道如何使用CLLocationManager - 實施這種「便利方法」的問題是什麼? – tcurdt 2009-01-20 00:04:51
我認爲問題並不那麼容易。通常情況下,它首先會返回一箇舊的位置,然後是一個非常不尋常的位置,然後是逐漸變好的位置,在什麼時候您決定擁有一個您想要的位置?這真的取決於你。 – rustyshelf 2009-01-20 00:42:21
好點,生鏽! – 2009-01-20 14:18:57