在iOS 下使用地图,是用CLLocationManager这个类来进行开发的,和别的类一样使用,(1创建,2.配置,3.开始使用)。添加一个第0步:添加CoreLoation.framework框架,引入#import
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter = 100.0;
[locationManager startUpdatingLocation];
:
(1)desiredAccuracy:选择的精确模式,官方定义可选的有:
extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);
extern const CLLocationAccuracy kCLLocationAccuracyBest;
extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;
extern const CLLocationAccuracy kCLLocationAccuracyKilometer;
extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;
其中一般常用的是kCLLocationAccuracyBest,它提供在设备使用电池供电时的最精确的定位,kCLLocationAccuracyBestForNavigation是在导航情况下最高精度.
(2)distanceFilter这个定义了移动时位置更新的距离,就是说距离偏移多少才开始重新定位.
接下来要实现CLLocationManagerDelegate中的方法,这些协议方法都是可选的.可是要得到位置就要实现这些代理方法.
locationManager:didUpdateLocations:
这是会得到最新位置的数据信息.传入的是一个数组.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
for(CLLocation *location in locations){
NSLog(@"---------%@-------",location);
}
CLGeocoder *geoCoder = [[CLGeocoder alloc]init];//反向解析,根据及纬度反向解析出地址
CLLocation *location = [locations objectAtIndex:0];
[geoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
for(CLPlacemark *place in placemarks)
{
NSDictionary *dict = [place addressDictionary];
NSLog(@"------addressDictionary-%@------",dict);
}
}];
}
还有地位失败时候的代理方法:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"----error------%@",[error domain]);
}
可是什么都没打印出来,是不是没有调用代理方法,可是明明设置自己为delegate了啊,是不是iOS 8下有问题?
果然是.
在iOS 8下必须额外多做两件事情.
(1)在info.plist文件中添加NSLocationAlwaysUsageDescription 这个键.
(2)在配置完CLLocation对象后要加入这句
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];//iOS 8才有,且必须用上
}
然后你就会得到这个提醒了
这个在真机中是显示的中文的,点击确定,能进入成功或者失败的代理方法了(如果不行,再在info.plist中添加privacy - location usage description和NSLocationWhenInUseUsageDescription键),这时可以得到打印出来的CLLocation和反向解析出来的地址精确信息:
可是这不对的啊,我切确的位置不是这个啊,是不是iOS 内置的高德地图的问题?可是用百度SDK定位出来的也是这个经纬度啊,然后用在线根据经纬度查确切地址
得到的确实是我所在的地址
这明显解析有问题.
查询后发现CLLocationManagerDelegate 有问题?
用MapKit.framework里面的MKMapViewDelegate的方法试试?
那是显示地图的框架,定义一个 MKMapView 对象并初始化;
@property (weak, nonatomic) IBOutlet MKMapView *mapView;//in .h 文件
//in viewDidLoad
self.mapView.showsUserLocation = YES;
self.mapView.delegate = self;
实现代理方法:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
CLLocation *newLocation = userLocation.location;
CLGeocoder *coder = [[CLGeocoder alloc]init];
[coder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
for(CLPlacemark *place in placemarks)
{
NSDictionary *dict = [ place addressDictionary];
NSLog(@"----city----%@",[dict objectForKey:@"Name"]);
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([userLocation.location coordinate], 250, 250);
self.mapView.region = region;
}}];
}
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error
{
NSLog(@"----error------%@",[error domain]);
}
得到的结果,经纬度:
位置:
这可是就对了,
这么神奇?
事实上如果不用 CLLocationManager,直接用MKMapView 居然也能正确显示地址!不过依然要在info.plist中添加NSLocationAlwaysUsageDescription 这个键.
否则无法定位。当然,还要引入MapKit框架并在.h或.m中#import <MapKit/MapKit.h>
出现:Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
这是说明还是要在CLLocationManager中调用:
[locationManager requestAlwaysAuthorization];
locationManager还是少不了.