在使用定位的时候,会觉得很繁琐,这里尝试使用 Block 进行封装.
由于定位可能在多处使用,这里我选择使用单例模式
1.创建单例的对象,下面是一个单例宏文件
// 单例
// .h文件
#define DZSingletonH(name) + (instancetype)share##name;
// .m文件
#define DZSingletonM(name) \
static id _instance; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
+ (instancetype)share##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
2.在. h 文件中使用 block 的形式定义一个方法
@interface DZLocationPositionTool : NSObject<CLLocationManagerDelegate>
// 上面单例的使用,. h 里面声明方法
DZSingletonH(Location)
- (void)locationSuccessed:(void(^)(CLLocation *location))successed failed:(void(^)(NSError *error))failed;
@end
3.通过上面的方法我们可以看到,是使用两个 block 处理不同的定位结果
#import "DZLocationPositionTool.h"
@interface DZLocationPositionTool()
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, copy) void(^locationSuccessed)(CLLocation *location);
@property (nonatomic, copy) void(^locationfaild)(NSError *error);
@end
@implementation DZLocationPositionTool
// 单例实现方法
DZSingletonM(Location)
- (CLLocationManager *)locationManager {
if (!_locationManager) {
_locationManager = [[CLLocationManager alloc]init];
_locationManager.delegate = self;
/*
设置定位服务的精度。该属性值支持
kCLLocationAccuracyBestForNavigation(导航级的最佳精确度)、
kCLLocationAccuracyBest(最佳精确度)、
kCLLocationAccuracy NearestTenMeters(10米误差)、
kCLLocationAccuracyHundredMeters(百米误差)、
kCLLocationAccuracyKilometer(千米误差)、
kCLLocationAccuracyThreeKilometers(三千米误差)
*/
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//设置CLLocationManager的自动过滤距离。也就是说,只有当设备在水平方向的位置改变超过该数值(以米为单位)指定的距离时才会生成一次位置改变的信号。
_locationManager.distanceFilter = 1000.0f;
// 设置iOS设备是否可暂停定位来节省电池的电量。如果该属性设为“YES”,则当iOS设备不再需要定位数据时,iOS设备可以自动暂停定位。
// self.locationManager.pausesLocationUpdatesAutomatically = YES;
// 宏定义判断版本号,下面有宏的具体实现
if (iOSLater(8.0)) {
[_locationManager requestWhenInUseAuthorization];
}
}
return _locationManager;
}
- (void)locationSuccessed:(void(^)(CLLocation *newLocation))successed failed:(void(^)(NSError *error))failed {
self.locationSuccessed = successed;
self.locationfaild = failed;
[self startLocation];
}
// 当授权定位状态改变时调用
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
NSLog(@"====%d", status);
/*
kCLAuthorizationStatusNotDetermined:定位服务授权状态是用户没有决定是否使用定位服务。
kCLAuthorizationStatusRestricted:定位服务授权状态是受限制的。可能是由于活动限制定位服务,用户不能改变。这个状态可能不是用户拒绝的定位服务。
kCLAuthorizationStatusDenied:定位服务授权状态已经被用户明确禁止,或者在设置里的定位服务中关闭。
kCLAuthorizationStatusAuthorizedAlways:定位服务授权状态已经被用户允许在任何状态下获取位置信息。包括监测区域、访问区域、或者在有显著的位置变化的时候。
kCLAuthorizationStatusAuthorizedWhenInUse:定位服务授权状态仅被允许在使用应用程序的时候。
kCLAuthorizationStatusAuthorized:这个枚举值已经被废弃了。他相当于kCLAuthorizationStatusAuthorizedAlways这个值。
*/
if (status == kCLAuthorizationStatusNotDetermined){
NSLog(@"用户没有决定是否使用定位服务");
}else if (status == kCLAuthorizationStatusAuthorizedAlways ||
status == kCLAuthorizationStatusAuthorizedWhenInUse ||
status == kCLAuthorizationStatusAuthorized) {
NSLog(@"用户允许");
[self startLocation];
} else {
NSLog(@"用户禁止使用");
}
}
#pragma mark CLLocationManager delegate
//定位成功调用
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
NSLog(@"定位成功!");
self.locationSuccessed(locations.lastObject);
}
// 开始定位
- (void)startLocation {
[self.locationManager startUpdatingLocation];
}
// 停止定位
- (void)stopUpdataLocation {
[self.locationManager stopUpdatingLocation];
}
// 错误信息
- (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
self.locationfaild(error);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
self.locationfaild(error);
}
@end
4.使用方法:
DZLocationPositionTool *tool = [DZLocationPositionTool shareLocation];
[tool locationSuccessed:^(CLLocation *location) {
NSLog(@"====%@", location);
} failed:^(NSError *error) {
NSLog(@"%@", error.description);
}];
更过开发细节请移步
如何更优雅的比较版本号
block