2013-06-19 50 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]; 


         }]; 
    } 
}