使用方式
//只获取一次
__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
网友评论