您的位置:首页 > 移动开发 > IOS开发

浅谈——适配所有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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: