我想在我的应用程序中完成的是获取当前用户位置并将其显示在屏幕上UILabel
。我想要一个NSString
当前用户的位置,其格式类似于:@"City, State/Country"
. 这将是应用程序启动时的一次性操作。
我之前没有在 iOS 中定位的经验,我想就此获得一些建议 - 我确信这是一项非常简单的任务。
我想在我的应用程序中完成的是获取当前用户位置并将其显示在屏幕上UILabel
。我想要一个NSString
当前用户的位置,其格式类似于:@"City, State/Country"
. 这将是应用程序启动时的一次性操作。
我之前没有在 iOS 中定位的经验,我想就此获得一些建议 - 我确信这是一项非常简单的任务。
过程如下:
添加CoreLocation.framework
到您的项目中。请参阅链接到库或框架。如果您想使用我在下面使用的地址簿常量,您可能还想将 添加AddressBook.framework
到您的项目中。
启动定位服务。为此,“显着变化”服务(准确度较低,但功耗较低)可能足以达到城市级别的准确度。
当位置管理器通知您用户的位置时,请对该位置执行反向地理编码。
停止定位服务。
因此,这可能看起来像:
#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];
}
请注意,位置管理器的位置通知取决于用户选择与您的应用程序共享,并且即使在最好的情况下,也会异步发生。同样,反向地理编码异步发生。
请参阅位置感知编程指南中的获取用户位置。
的使用-reverseGeocodeLocation:completionHandler:
。CLGeocoder
试试这个代码片段,唯一的技巧是你从地理编码器返回的CLPlacemark
(参见文档以获取可用信息)有一堆并不总是一致的信息,这是我在一个旧项目中的尝试之一,试图测试位置、街道名称等...使用您的用例进行测试以找到合适的匹配项:
- (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];
}];
}
}
我找到了一个关于这个主题的非常好的和简单的教程 - http://www.appcoda.com/how-to-get-current-location-iphone-user/
希望对其他人有所帮助!
看一下 CLGeocoder 的 reverseGeocodeLocation:completionHandler: 方法:
首先,您必须使用 CLLocationManager 来获取代表用户当前位置的 CLLocation。