2013-06-19 6 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-load? 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]; 


         }]; 
    } 
} 
Смежные вопросы