最近在做定位功能,只需要获取当前位置信息,包括经纬度、位置等,不需要持续获取。
对CoreLocation的封装。将定位相关的代码从 Controller 中分离,封装到 NSObject 对象中。采用 代理方法 降低代码的分散度,方便调用亦易于获取位置信息。
1,初始化
//初始化 - (instancetype)init { if (self = [super init]) { //创建CLLocationManager对象 _locationManager = [[CLLocationManager alloc] init]; _locationManager.desiredAccuracy = kCLLocationAccuracyBest; _locationManager.distanceFilter = 10.0; _locationManager.delegate = self; //请求用户授权 if ([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { //当用户使用的时候授权 [_locationManager requestWhenInUseAuthorization]; } } return self; }
2,代理方法
#pragma mark - CLLocationManagerDelegate /** location.coordinate:坐标,包含经纬度 location.altitude:设备海拔高度单位是米 location.course:设置前进方向 location.horizontalAccuracy:水平精准度 location.verticalAccuracy:垂直精准度 location.timestamp:定位信息返回的时间 location.speed:设备移动速度单位是米/秒,适用于行车速度而不太适用于不行 */ - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{ //结束,防止重发定位 //如果只需要获取一次,可以获取到位置之后就停止 [self.locationManager stopUpdatingLocation]; if (self.locationTimes != 0) return; //拿到最新的location CLLocation *currentLocation = [locations lastObject]; //反编码 CLGeocoder * geoCoder = [[CLGeocoder alloc] init]; [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { if (placemarks.count > 0) { //将字典转为模型 NSDictionary *dic = [self getInfoWithPlacemark:placemarks[0]]; LocationModel *model = [[LocationModel alloc]init]; [model setValuesForKeysWithDictionary:dic]; //首次判断代理是否存在,并在代理能够响应代理方法时才执行代理方法 if (self.ldelegate && [self.ldelegate respondsToSelector:@selector(doSomethingAfterGetCityInformation:)]) { [self.ldelegate doSomethingAfterGetCityInformation:model]; } } else if (error == nil && placemarks.count == 0) { NSLog(@"No location and error return"); } else if (error) { NSLog(@"location error: %@ ",error); } }]; self.locationTimes ++; }
/** 授权状态 */ - (void)locationManager:(CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{ if(status ==kCLAuthorizationStatusNotDetermined) { NSLog(@"等待用户授权"); }else if(status ==kCLAuthorizationStatusAuthorizedAlways|| status ==kCLAuthorizationStatusAuthorizedWhenInUse){ NSLog(@"授权成功"); //开始定位 [self.locationManager startUpdatingLocation]; }else{ NSLog(@"授权失败"); } }
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ NSLog(@"E:%@",error); if ([error code] == kCLErrorDenied) { NSLog(@"错误:拒绝定位"); }else if ([error code] == kCLErrorLocationUnknown) { NSLog(@"错误:无法获取定位"); }else { NSLog(@"%@",error.localizedDescription); } }
3,整理位置信息
#pragma mark - 整理位置信息 - (NSDictionary *)getInfoWithPlacemark:(CLPlacemark *)placemark { // 经纬度 CLLocationCoordinate2D coordinate = placemark.location.coordinate; NSString *longitude = [NSString stringWithFormat:@"%f",coordinate.longitude]; NSString *latitude = [NSString stringWithFormat:@"%f",coordinate.latitude]; // 省/市/县(区)/街道/详细地址 NSString *province = placemark.administrativeArea; NSString *locality = placemark.locality; province = province ? province : placemark.locality;//若省不存在则为直辖市 NSString *subCity = placemark.subLocality; NSString *street = placemark.addressDictionary[@"Street"]; // NSString *name = placemark.name; NSString *address; if ([province isEqualToString:locality]) { address = [NSString stringWithFormat:@"%@%@%@",locality,subCity,street]; }else { address = [NSString stringWithFormat:@"%@%@%@%@",province,locality,subCity,street]; } NSDictionary *dic = @{@"longitude" :longitude, @"latitude" :latitude, @"province" :province, @"locality" :locality, @"subLocality":subCity, @"street" :street, @"address" :address}; return dic; }
4,使用
#import "ACCoreLocationViewController.h" #import <CoreLocation/CoreLocation.h> @interface ACCoreLocationViewController ()<CLLocationManagerDelegate> @property (nonatomic,strong) CLLocationManager *locationManager; @end @implementation ACCoreLocationViewController - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.locationObject start]; } - (void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [self.locationObject end]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.locationObject = [[ACCoreLocationObject alloc]init]; _locationObject.ldelegate = self; } /** 代理方法 */ -(void)doSomethingAfterGetCityInformation:(LocationModel *)model{ NSLog(@"城市%@",model.locality); }
注意:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations;
这个方法每隔一段时间就会调用一次,所以如果只需要定位一次的话,要做相应的处理。
- 只获取一次定位
[self.locationManager requestLocation];
- 一直持续获取定位
[self.locationManager startUpdatingLocation];
参考文章