2013-06-19 109 views
1

我想在我的應用程序中完成的任務是獲取當前用戶位置並將其顯示在屏幕上UILabel。我希望有一個NSString當前用戶的位置,格式類似於:@"City, State/Country"。這將是應用程序發佈之初的一次性操作。iOS獲取用戶位置爲NSString

我沒有在iOS中的位置的任何經驗,我想就這一個獲得一些建議 - 我相信這是一個相當簡單的任務。

+0

你看過與定位服務相關的文檔嗎? – rmaddy

+0

請參閱http:// stackoverflow。com/questions/6683976/ios-corelocation-get-users-location-when-the-app-loads?rq = 1 – rmaddy

+0

@rmaddy這不是很接近,但謝謝! –

回答

8

的過程如下:

  1. 添加CoreLocation.framework到您的項目。見Linking to a Library or a Framework。如果您想使用下面我使用的地址簿常量,則可能還需要將AddressBook.framework添加到您的項目中。

  2. Start location services。爲此,「重大改變」服務(不太準確,但功耗較低)可能足以滿足城市級別的準確性。

  3. 當位置管理器通知您用戶的位置,然後perform a reverse geocode該位置。

  4. 停止位置服務。

因此,可能看起來像:

#import <CoreLocation/CoreLocation.h> 
#import <AddressBook/AddressBook.h> 

@interface ViewController() <CLLocationManagerDelegate> 

@property (nonatomic, strong) CLLocationManager *locationManager; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [self startSignificantChangeUpdates]; 
} 

- (void)startSignificantChangeUpdates 
{ 
    if ([CLLocationManager locationServicesEnabled]) 
    { 
     if (!self.locationManager) 
      self.locationManager = [[CLLocationManager alloc] init]; 

     self.locationManager.delegate = self; 
     [self.locationManager startMonitoringSignificantLocationChanges]; 
    } 
} 

- (void)stopSignificantChangesUpdates 
{ 
    [self.locationManager stopUpdatingLocation]; 
    self.locationManager = nil; 
} 

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 
{ 
    CLLocation *location = [locations lastObject]; 

    CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 

    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { 
     CLPlacemark *placemark = placemarks[0]; 
     NSDictionary *addressDictionary = [placemark addressDictionary]; 
     NSString *city = addressDictionary[(NSString *)kABPersonAddressCityKey]; 
     NSString *state = addressDictionary[(NSString *)kABPersonAddressStateKey]; 
     NSString *country = placemark.country; 

     self.label.text = [NSString stringWithFormat:@"%@, %@, %@", city, state, country]; 
    }]; 

    [self stopSignificantChangesUpdates]; 
} 

注意,位置的位置管理的通知是偶然當用戶選擇把你的應用程序共享,並會發生,即使在最好的情況下,異步。同樣,反向地理編碼也是異步發生的。

請參閱Getting User Location位置感知編程指南。

2

使用-reverseGeocodeLocation:completionHandler:CLGeocoder

試試這個代碼片段中,唯一的訣竅是,CLPlacemark(見Documentation可用的信息),你從地理編碼器取回有一堆信息的這並不總是一致,這是我的嘗試之一從較早的項目,試圖測試位置,街道名稱等......與您的使用情況下的測試來找到一個很好的匹配:

- (void)getLocationStringForCoordinates:(CLLocationCoordinate2D)coordinates { 

    if (CLLocationCoordinate2DIsValid(coordinates)) { 

     CLLocation *photoLocation = [[CLLocation alloc] initWithLatitude:coordinates.latitude longitude:coordinates.longitude]; 
     CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 

     [geocoder reverseGeocodeLocation:photoLocation 
         completionHandler:^(NSArray *placemarks, NSError *error) { 
          CLPlacemark *locationPlacemark = [placemarks lastObject]; 

          // Location (popular name, street, area) 
          NSString *location = locationPlacemark.subLocality ? locationPlacemark.subLocality : (locationPlacemark.name ? locationPlacemark.name : locationPlacemark.thoroughfare); 

          // sometimes the location can be the same 
          // as the city name (for small villages), if so 
          // make sure location is nil to skip it 
          // else if 
          // the location name is not being used but is very short 9less then 20 letters, use that instead 
          if([locationPlacemark.name isEqualToString:locationPlacemark.locality] && [location isEqualToString:locationPlacemark.name]) 
           location = @""; 
          else if (![locationPlacemark.name isEqualToString:location] && locationPlacemark.name.length < 20) 
           location = locationPlacemark.name; 

          // city 
          NSString *city = locationPlacemark.subAdministrativeArea ? locationPlacemark.subAdministrativeArea : locationPlacemark.locality; 

          city = city.length > 0 ? [@", " stringByAppendingString:city] : city; 

          NSString *locationName = [NSString stringWithFormat:@"%@%@", location, city]; 


         }]; 
    } 
}