工具实例使用单例,便于全局调取经纬度信息
static DJLocationTool *manager;
static dispatch_once_t onceToken;
+ (instancetype)shareInstance {
if (!manager) {
dispatch_once(&onceToken, ^{
manager = [[DJLocationTool alloc] init];
});
}
return manager;
}
添加经纬度属性以及城市名称等属性,可自行扩展其他地址属性
@property (nonatomic, strong) NSString *lon;
@property (nonatomic, strong) NSString *lat;
@property (nonatomic, strong) NSString *city;
CLLocationManager 定位服务
@property (nonatomic, strong) CLLocationManager *locationmanager;//定位服务
懒加载,根据实际需要设置distanceFilter,超出设置的范围值后会再次定位
- (CLLocationManager *)locationmanager
{
if (!_locationmanager) {
_locationmanager = [[CLLocationManager alloc]init];
_locationmanager.delegate = self;
[_locationmanager requestWhenInUseAuthorization];
//设置寻址精度
_locationmanager.desiredAccuracy = kCLLocationAccuracyBest;
_locationmanager.distanceFilter = 5000.0;
}
return _locationmanager;
}
开始定位
- (void)getLocation
{
//判断定位功能是否打开
if ([CLLocationManager locationServicesEnabled]) {
[self.locationmanager startUpdatingLocation];
}
}
定位结果回调
#pragma mark CoreLocation delegate (定位失败)
//定位失败后调用此代理方法
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
// 如果定位失败,两秒后再次定位。主要解决第一次安装APP请求定位权限时的时间差
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"!!!!!!!!!!!!!!!!");
[self getLocation];
});
//设置提示提醒用户打开定位服务
NSLog(@"请在设置中打开定位");
}
#pragma mark 定位成功后则执行此代理方法
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
[self.locationmanager stopUpdatingLocation];
//旧址
CLLocation *currentLocation = [locations lastObject];
//打印当前的经度与纬度
self.lon = [NSString stringWithFormat:@"%f", currentLocation.coordinate.longitude];
self.lat = [NSString stringWithFormat:@"%f", currentLocation.coordinate.latitude];
//根据经纬度反编译地址信息
CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count > 0) {
CLPlacemark *placeMark = placemarks[0];
self.city = placeMark.locality;
self.locationBlock ? self.locationBlock(self.lon, self.lat, self.city) : nil;
// YMLog(@"当前用户所在城市:%@",placeMark.locality);
// YMLog(@"%@",placeMark.country);//当前国家
// YMLog(@"%@",placeMark.locality);//当前城市
// YMLog(@"%@",placeMark.subLocality);//当前位置
// YMLog(@"%@",placeMark.thoroughfare)//当前街道
// YMLog(@"%@",placeMark.name);//具体地址 市 区 街道
} else if (error == nil && placemarks.count == 0) {
NSLog(@"没有地址返回");
} else if (error) {
NSLog(@"%@",error);
}
}];
}
定位成功的block回调,用于在定位成功后做一些业务处理
@property (nonatomic, copy) void (^locationBlock)(NSString *lon, NSString *lat, NSString *city);
注意事项:
1、开启定位权限需要在info.plist中添加Privacy - Location When In Use Usage Description,在使用期间获取定位,并在对应值中写上实际的应用场景。
2、如果只是普通定位获取经纬度需求,不需要添加后台定位Privacy - Location Always Usage Description,添加后台定位需要开启Background Modes,并实现相应后台配置。