美文网首页
iOS 获取经纬度 地理编码

iOS 获取经纬度 地理编码

作者: CoderLGL | 来源:发表于2020-04-11 11:38 被阅读0次

使用方式

//只获取一次
 __block  BOOL isOnece = YES;
 [GLLocationManager getGLLocationWithSuccess:^(CLLocation * _Nonnull location, CLPlacemark * _Nonnull Placemark) {
     isOnece = NO;
     
     if (!isOnece) {
         [GLLocationManager stop];
     }
 } Failure:^(NSError * _Nonnull error) {
     
 }];


// 持续定位
[GLLocationManager getGLLocationWithSuccess:^(CLLocation * _Nonnull location, CLPlacemark * _Nonnull Placemark) {

} Failure:^(NSError * _Nonnull error) {
    
}];

.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
NS_ASSUME_NONNULL_BEGIN

typedef void(^GLLocationSuccess) (CLLocation *location,CLPlacemark *Placemark);
typedef void(^GLLocationFailed) (NSError *error);

@interface GLLocationManager : NSObject<CLLocationManagerDelegate>

@property (nonatomic, copy) GLLocationSuccess locationSuccess;
@property (nonatomic, copy) GLLocationFailed locationFailed;

/// 创建单例
+(instancetype)shareInstance;

/// 获取位置信息
+ (void)getGLLocationWithSuccess:(GLLocationSuccess)success Failure:(GLLocationFailed)failure;

/// 停止定位
+ (void)stop;


.m

#import "GLLocationManager.h"

@interface GLLocationManager ()

@property (strong, nonatomic)CLLocationManager *locationManager;

//通过经纬度反编码得到具体地址需要用得到
@property (strong,nonatomic) CLGeocoder *geocoder;


@end

// 创建静态对象 防止外部访问
static GLLocationManager *_instance = nil;

@implementation GLLocationManager


#pragma mark ==========创建单例==========
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    //    @synchronized (self) {
    //        // 为了防止多线程同时访问对象,造成多次分配内存空间,所以要加上线程锁
    //        if (_instance == nil) {
    //            _instance = [super allocWithZone:zone];
    //        }
    //        return _instance;
    //    }
    // 也可以使用一次性代码
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    });
    return _instance;
}

// 为了使实例易于外界访问 我们一般提供一个类方法
// 类方法命名规范 share类名|default类名|类名
+(instancetype)shareInstance{
    //return _instance;
    // 最好用self 用AppManager他的子类调用时会出现错误
    return [[self alloc] init];
}
// 为了严谨,也要重写copyWithZone 和 mutableCopyWithZone
-(id)copyWithZone:(NSZone *)zone{
    return _instance;
}
-(id)mutableCopyWithZone:(NSZone *)zone{
    return _instance;
}

#pragma mark ========== 获取经纬度 ==========


- (instancetype)init
{
    self = [super init];
    if (self) {
        [self getCurrentLocation];
    }
    return self;
}

- (void)getCurrentLocation
{
    // 实例化 CLGeocoder 对象
    self.geocoder = [[CLGeocoder alloc] init];
    
    
    self.locationManager = [[CLLocationManager alloc] init];
    // 将视图控制器自身设置为CLLocationManager的delegate
    // 因此该视图控制器需要实现CLLocationManagerDelegate协议
    self.locationManager.delegate = self;
    // 设置定位精度:最佳精度
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    // 设置距离过滤器为10.0米,表示每移动10.0米更新一次位置
    // 定位精确度越高, 越耗电, 而且, 定位时间越长
    self.locationManager.distanceFilter = 10.0;
    
    /* Info.plist里面加上2项
     Privacy - Location When In Use Usage Description      Boolean YES
     Privacy - Location Always and When In Use Usage Description   Boolean YES
     */
    
    // 请求授权 requestWhenInUseAuthorization用在>=iOS8.0上
    // respondsToSelector: 前面manager是否有后面requestWhenInUseAuthorization方法
    if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [self.locationManager requestWhenInUseAuthorization];
        [self.locationManager requestAlwaysAuthorization];
    }
    
}
// 每隔一段时间就会调用
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    //获取经纬度坐标
    CLLocation *location = [locations objectAtIndex:0];
    // 反编码
    [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (error || placemarks.count == 0) {
            //编码失败,找不到地址
            NSLog(@"编码失败,找不到地址 -- 你现在可能在火星上");
        }else{
            /*
             编码成功
             */
            CLPlacemark *firstPlacemark = [placemarks firstObject];
            self.locationSuccess ? self.locationSuccess(location, firstPlacemark) : nil;
            /*
             firstPlacemark.ISOcountryCode  国家编码 :中国(CN)
             firstPlacemark.country   国家
             firstPlacemark.administrativeArea  省份
             firstPlacemark.locality   城市
             firstPlacemark.subLocality  区
             firstPlacemark.thoroughfare 街道
             firstPlacemark.addressDictionary  字典,包含地址的一些基本信息
             */
            NSLog(@"编码成功 -- %@%@%@",firstPlacemark.country,firstPlacemark.administrativeArea,firstPlacemark.locality);
        }
    }];
}

//失败代理方法
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    self.locationFailed(error);
    if ([error code] == kCLErrorDenied) {
        NSLog(@"访问被拒绝");
    }
    if ([error code] == kCLErrorLocationUnknown) {
        NSLog(@"无法获取位置信息");
    }
    NSLog(@"无法获取位置信息");
}


- (void)getGLLocationWithSuccess:(GLLocationSuccess)success Failure:(GLLocationFailed)failure{
    self.locationSuccess  = [success copy];
    self.locationFailed  = [failure copy];
    // 停止上一次的
    [self.locationManager stopUpdatingLocation];
    // 开始新的数据定位
    [self.locationManager startUpdatingLocation];
}

+ (void)getGLLocationWithSuccess:(GLLocationSuccess)success Failure:(GLLocationFailed)failure{
    
    [[GLLocationManager shareInstance] getGLLocationWithSuccess:success Failure:failure];
}


- (void)stop {
    [self.locationManager stopUpdatingLocation];
}


+ (void)stop {
    [[GLLocationManager shareInstance] stop];
}

@end

相关文章

网友评论

      本文标题:iOS 获取经纬度 地理编码

      本文链接:https://www.haomeiwen.com/subject/mczemhtx.html