iOS开发

使用 Block封装定位

2016-12-05  本文已影响83人  明月钓无痕

在使用定位的时候,会觉得很繁琐,这里尝试使用 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

上一篇 下一篇

猜你喜欢

热点阅读