定位
常用方法的介绍
CLLocationManager位置管理器,我们的有关于位置的方法和属性都是通过它来管理设置的。
+ (BOOL)locationServicesEnabled监测设备是否开启定位功能。
- (void)requestAlwaysAuthorization请求用户设置在程序运行期间和程序在前台和后台,都开启定位。需要在info.plist文件中添加相应的字段(键值对)来配合该方法的使用。NSLocatiodenAlwaysUsageDescription键 值(提示信息)
- (void)requestWhenInUseAuthorization请求用户设置只在程序运行期间才开启定位服务。需要在info.plist文件中添加相应的字段(键值对)来配合该方法的使用。NSLocationWhenInUseUsageDescription键 值(提示信息)
- (void)startUpdatingLocation开启定位,在所有相关的属性设置完毕之后,需要开启定位。
需要设置的属性
- 设置定位的频率,每隔多少米定位一次。
距离筛选器
@property(assign, nonatomic) CLLocationDistance distanceFilter;
如果将下面的常量赋值给这个属性就可以将位置管理器返回到没有设置筛选器的默认状态。
- 设置精确度(精确度是根据当前应用的需求来定的,不是越精确越好,精确度越高越耗电)。
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
//下面是可以被设置的值
extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation;
extern const CLLocationAccuracy kCLLocationAccuracyBest;
extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;
extern const CLLocationAccuracy kCLLocationAccuracyKilometer;
extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;
- CLLocationManager代理属性,用来指定代理人。
@property(assign, nonatomic, nullable) id<CLLocationManagerDelegate> delegate;
示例代码
注意:在初始化位置管理器的时候,我们需要将位置管理器的对象设置成为实例变量或者是属性,如果直接初始化为局部实例变量,这时候它的协议方法有可能会不执行。
在代码都正常的情况下,定位如果失败,有可能是网络环境的问题,我们可以换一下网络试试
在延展中需要声明属性
@interface RootViewController ()<CLLocationManagerDelegate>
@property (strong, nonatomic)CLLocationManager *locationManager;//定位服务的管理对象。
@end
self.locationManager = [[CLLocationManager alloc]init];初始化一个位置管理器
BOOL openLocationServices = [CLLocationManager locationServicesEnabled];
if (openLocationServices) {
NSLog(@"已经开启定位");
[self.locationManager requestAlwaysAuthorization];//请求用户总是使用定位服务
self.locationManager.distanceFilter = 10.0;//设置定位的频率,
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//设置精确度
self.locationManager.delegate = self;//设置代理
[self.locationManager startUpdatingLocation];//开始定位
}else{
NSLog(@"无法获取你的位置信息,为了更好的为你服务,请在设置隐私定位服务中开启定位服务");
}
定位的代理方法
位置管理器代理必须遵循CLLocationManagerDelegate协议,该协议定义了多个方法,其中有两个方法,当位置管理器已经确定当前位置或者当它检测到位置的更改时将调用。
在方法中你会见到一个CLLocationCoordinate2D它是一个结构体,里面包含了经纬度
typedef struct {
CLLocationDegrees latitude;//纬度
CLLocationDegrees longitude;//经度
} CLLocationCoordinate2D;
如果想创建一个CLLocationCoordinate2D我们一般使用如下的方法
CLLocationCoordinate2D CLLocationCoordinate2DMake(CLLocationDegrees latitude, CLLocationDegrees longitude)
- 定位获取location信息的时候会执行的协议方法
-(void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations{
if (locations && locations.count) {
CLLocationCoordinate2D lastLocation = locations.lastObject.coordinate;
NSLog(@"纬度%f 经度%f",lastLocation.latitude,lastLocation.longitude);
}
}
- 定位出现错误的时候
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(@"定位失败-------%@",error.description);
}
地理编码和反地理编码
使用CLGeocoder可以完成地理编码和反地理编码
- 地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等)
地理编码的方法
-(void)geocodeAddressString:(NSString *)addressString completionHandler:
(CLGeocodeCompletionHandler)completionHandler;
- 反地理编码:根据给定的经纬度,获得具体的位置信息。
反地理编码的方法
-(void)reverseGeocodeLocation:(CLLocation *)location completionHandler:
(CLGeocodeCompletionHandler)completionHandler;
地理编码
- 使用CLGeocoder类来创建一个实例对象
CLGeocoder *geo = [[CLGeocoder alloc]init];
- 使用创建好的实例对象来调用地理编码的方法
CLPlacemark的字面意思是地标,它里面封装了具体的位置信息,我们可以根据需要取出我们需要的信息。
[geo geocodeAddressString:@"这里写地点名称" completionHandler:^(NSArray<CLPlacemark *> * _Nullable
placemarks, NSError * _Nullable error) {
CLPlacemark *newPlacemarks = placemarks.lastObject;
NSLog(@"经度 %f, 纬度 %f",
newPlacemarks.location.coordinate.latitude,newPlacemarks.location.coordinate.longitude);
NSLog(@"----+++++++++++++++++++++++%@",newPlacemarks.name);
}];
反地理编码
- 使用CLGeocoder类来创建一个实例对象
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
- 使用创建好的实例对象来调用反地理编码的方法
[geocoder reverseGeocodeLocation:@"这里填写一个经纬度" completionHandler:
^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
CLPlacemark *newPlacemark = placemarks.lastObject;
NSLog(@"%@",newPlacemark.country);
NSLog(@"%@",newPlacemark.addressDictionary);
NSLog(@"%@",[newPlacemark.addressDictionary objectForKey:@"City"]);
NSLog(@"%@",newPlacemark.name);
NSLog(@"%@",newPlacemark.location);
}];