浅谈——适配所有IOS版本的反地理编码的代理转block封装
2015-09-24 00:22
519 查看
LSLLocationTool工具类的声明文件.h
#import <Foundation/Foundation.h> #import <CoreLocation/CoreLocation.h> #import "Single.h" /** 接口block */ typedef void(^ResultBlock)(CLLocation *location, CLPlacemark *placemark, NSString *error); @interface LSLLocationTool : NSObject /** 用宏实现类单利模式的声明 */ SingleInterface(LSLLocationTool); /** 反地理编码接口 */ - (void)getCurrentLocation:(ResultBlock)block; @end
LSLLocationTool工具类的实现文件.m
#import "LSLLocationTool.h" #import <UIKit/UIKit.h> /** 判断当前ios版本宏 */ #define isIOS(version) ([[UIDevice currentDevice].systemVersion floatValue] >= version) @interface LSLLocationTool()<CLLocationManagerDelegate> /** 回调代码 */ @property(nonatomic,copy)ResultBlock block; /** 位置管理者 */ @property(nonatomic,strong)CLLocationManager *locationManager; /** 地理编码 */ @property(nonatomic,strong)CLGeocoder *geocoder; @end @implementation LSLLocationTool /** 用宏实现类单利模式的实现 */ SingleImplement(LSLLocationTool); #pragma mark - 懒加载 - (CLLocationManager *)locationManager { if (!_locationManager) { _locationManager = [[CLLocationManager alloc] init]; _locationManager.delegate = self; // 获取info.plist 里面的键值对 NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; // iOS8.0之后, 必须手动请求定位授权 if (isIOS(8.0)) { // 获取前后台定位描述(看其他开发者到底有没有添加这个key) NSString *alwaysStr = infoDict[@"NSLocationAlwaysUsageDescription"]; // 获取前后台定位描述(看其他开发者到底有没有添加这个key) NSString *whenInUseStr = infoDict[@"NSLocationWhenInUseUsageDescription"]; // 判断其它开发者, 到底填写的是哪个key if([alwaysStr length] > 0){ [_locationManager requestAlwaysAuthorization]; }else if ([whenInUseStr length] > 0){ [_locationManager requestWhenInUseAuthorization]; // 如果请求的是前台定位授权, 如果想要在后台获取用户位置, 提醒其他开发者, 勾选后台模式location updates NSArray *backModes = infoDict[@"UIBackgroundModes"]; if (![backModes containsObject:@"location"]) { NSLog(@"当前授权模式是前台定位授权, 如果想要在后台获取位置, 需要勾选后台模式location updates"); }else { // 代表当前勾选后台模式, 而且是前台定位授权 if(isIOS(9.0)){ _locationManager.allowsBackgroundLocationUpdates = YES; } } }else{ NSLog(@"如果在iOS8.0之后获取用户位置, 必须主动填写info.plist文件中的key NSLocationAlwaysUsageDescription 或者 NSLocationWhenInUseUsageDescription"); } }else{// ios8.0之前 // 如果请求的是前台定位授权, 如果想要在后台获取用户位置, 提醒其他开发者, 勾选后台模式location updates NSArray *backModes = infoDict[@"UIBackgroundModes"]; if (![backModes containsObject:@"location"]) { NSLog(@"当前授权模式, 如果想要在后台获取位置, 需要勾选后台模式location updates"); } } } return _locationManager; } - (CLGeocoder *)geocoder { if (!_geocoder) { _geocoder = [[CLGeocoder alloc] init]; } return _geocoder; } #pragma mark - 反地理编码接口的实现 - (void)getCurrentLocation:(ResultBlock)block { // 记录代码块 self.block = block; // 判断用户是否开启定位 if ([CLLocationManager locationServicesEnabled] ) { [self.locationManager startUpdatingLocation]; }else{ self.block(nil,nil,@"用户未开启定位服务"); } } #pragma mark - <CLLocationManagerDelegate> 实现代理方法 /** * 定位到之后调用 * * @param manager 位置管理者 * @param locations 位置数组 */ - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { CLLocation *location = [locations firstObject]; // 判断位置是否可用 if (location.horizontalAccuracy >= 0) { [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { if (error == nil) { CLPlacemark *placemark = [placemarks firstObject]; self.block(location,placemark,nil); }else{ self.block(location,nil,@"反编码失败"); } }]; } // 只需要获取用户位置一次,则直接停止 [manager stopUpdatingLocation]; } /** * 当前授权状态发生改变时调用 * * @param manager 位置管理者 * @param status 状态 */ - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { switch (status) { // 用户还未决定 case kCLAuthorizationStatusNotDetermined: { NSLog(@"用户还未决定"); break; } // 问受限 case kCLAuthorizationStatusRestricted: { NSLog(@"访问受限"); self.block(nil, nil, @"访问受限"); break; } // 定位关闭时和对此APP授权为never时调用 case kCLAuthorizationStatusDenied: { // 定位是否可用(是否支持定位或者定位是否开启) if([CLLocationManager locationServicesEnabled]) { NSLog(@"定位开启,但被拒"); self.block(nil, nil, @"被拒绝"); }else { NSLog(@"定位关闭,不可用"); self.block(nil, nil, @"定位关闭,不可用"); } break; } // 获取前后台定位授权 // case kCLAuthorizationStatusAuthorized: // 失效,不建议使用 case kCLAuthorizationStatusAuthorizedAlways: { NSLog(@"获取前后台定位授权"); break; } // 获得前台定位授权 case kCLAuthorizationStatusAuthorizedWhenInUse: { NSLog(@"获得前台定位授权"); break; } default: break; } } @end
使用示例:
#import "ViewController.h" #import "LSLLocationTool.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [[LSLLocationTool shareLSLLocationTool] getCurrentLocation:^(CLLocation *location, CLPlacemark *placemark, NSString *error) { if([error length] > 0){ NSLog(@"报错--%@", error); }else{ NSLog(@"%@", placemark.name); } }]; } @end
相关文章推荐
- IOS 小例子,输出一个图形的坐标,颜色,形状。
- IOS6屏幕旋转详解(自动旋转、手动旋转、兼容IOS6之前系统)
- iOS中使用正则表达式NSRegularExpression 来验证textfiled输入的内容
- iOS AutoLayout自动布局中级开发教程(2)-等宽等高等中心
- iOS开发- OAuth2.0认证和SSO授权
- iOS开发-数据加密算法AES
- iOS开发-调整按钮的图片文字位置
- iOS开发-Xcode6应用程序国际化本地化
- IOS版应用商店应用源码
- iOS经典讲解之线程锁NSLock案例(卖火车票)
- 【iPhone/iPad】苹果iOS9正式版更新升级及固件刷机教程
- iOS学习 用代码实现界面 控件注解
- iOS 动画之CALayer动画
- ios激情详解之动画3D旋转晃动
- iOS本地化国际化多语言支持
- 【iOS】KVC 和 KVO 的使用场景
- iOS9 News 应用
- iOS 开发中实现打电话功能实用代码
- 《ios应用开发详解》1-3章
- 《ios应用开发详解》目录篇