Commit a7efe25cac415480934a84fcbca9ba0d43d6d0f1

Authored by 梁星国
1 parent 2fde247f

提交系统定位

CNLiveLocationManager.h 0 → 100644
  1 +//
  2 +// CNLiveLocationManager.h
  3 +// LocationManager
  4 +//
  5 +// Created by 梁星国 on 2018/9/19.
  6 +// Copyright © 2018年 cnlive. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import <CoreLocation/CoreLocation.h>
  11 +
  12 +@class CNLivePlacemark;
  13 +
  14 +typedef void (^LocationCoordinate2DBlock) (CLLocationDegrees latitude, CLLocationDegrees longitude);//经纬度信息
  15 +typedef void (^CNLivePlacemarkBlock) (CNLivePlacemark *placemark);//地理信息
  16 +
  17 +typedef void (^Failure)(id error);//失败
  18 +
  19 +@interface CNLiveLocationManager : NSObject
  20 +
  21 +/**
  22 + 释放单例
  23 + */
  24 ++(void)attempDealloc;
  25 +
  26 +/**
  27 + 定位回调
  28 +
  29 + @param coordinate2DBlock 经纬度
  30 + @param failure 无信息或有错误
  31 + */
  32 ++ (void)getLocation:(LocationCoordinate2DBlock)coordinate2DBlock failure:(Failure)failure;
  33 +
  34 +/**
  35 + 定位停止
  36 + */
  37 ++ (void)stop;
  38 +
  39 +/**
  40 + 是否启用定位服务
  41 +
  42 + @return 是否启用定位服务
  43 + */
  44 ++ (BOOL)locationServicesEnabled;
  45 +
  46 +/**
  47 + 反向地理编码获取地址信息
  48 +
  49 + @param latitude 纬度
  50 + @param longitude 经度
  51 + @param placemarkBlock 地理信息
  52 + @param failure 无信息或有错误
  53 + */
  54 ++ (void)getLocationWithLatitude:(NSString *)latitude longitude:(NSString *)longitude placemarkBlock:(CNLivePlacemarkBlock)placemarkBlock failure:(Failure)failure;
  55 +
  56 +/**
  57 + 反向地理编码获取地址信息
  58 +
  59 + @param coordinate2D 经纬度
  60 + @param placemarkBlock 地理信息
  61 + @param failure 无信息或有错误
  62 + */
  63 ++ (void)getLocationWithCoordinate2D:(CLLocationCoordinate2D)coordinate2D PlacemarkBlock:(CNLivePlacemarkBlock)placemarkBlock failure:(Failure)failure;
  64 +
  65 +/**
  66 + 地理编码获取经纬度
  67 +
  68 + @param address 地址
  69 + @param coordinate2DBlock 经纬度信息
  70 + @param failure 无信息或有错误
  71 + */
  72 ++ (void)getLocationWithAddress:(NSString *)address coordinate2DBlock:(LocationCoordinate2DBlock)coordinate2DBlock failure:(Failure)failure;
  73 +
  74 +@end
  75 +
  76 +
  77 +/** 只限制中国使用,其他国家使用高德优先 */
  78 +@interface CNLivePlacemark: NSObject
  79 +
  80 +/** id */
  81 +@property (nonatomic, assign) int placemarkId;
  82 +/** 类型 */
  83 +@property (nonatomic, copy) NSString *type;
  84 +/** 国家 */
  85 +@property (nonatomic, copy) NSString *country;
  86 +/** 省 */
  87 +@property (nonatomic, copy) NSString *province;
  88 +/** 城市 */
  89 +@property (nonatomic, copy) NSString *city;
  90 +/** 县(区) */
  91 +@property (nonatomic, copy) NSString *county;
  92 +/** 地址 */
  93 +@property (nonatomic, copy) NSString *address;
  94 +
  95 +/** 初始化 */
  96 ++ (CNLivePlacemark *)initWithCLPlacemark:(CLPlacemark *)placemark;
  97 +/** 取得省市 */
  98 +- (NSString *)getProvinceAndCity;
  99 +
  100 +@end
CNLiveLocationManager.m 0 → 100644
  1 +
  2 +//
  3 +// CNLiveLocationManager.m
  4 +// LocationManager
  5 +//
  6 +// Created by 梁星国 on 2018/9/19.
  7 +// Copyright © 2018年 cnlive. All rights reserved.
  8 +//
  9 +
  10 +#import "CNLiveLocationManager.h"
  11 +
  12 +@interface CNLiveLocationManager ()<CLLocationManagerDelegate>
  13 +
  14 +@property (nonatomic, strong) CLLocationManager *locationManager;
  15 +@property (nonatomic, strong) CLGeocoder *geocoder;
  16 +
  17 +@property (nonatomic, copy) LocationCoordinate2DBlock coordinate2DBlock;
  18 +@property (nonatomic, copy) Failure failure;
  19 +
  20 +
  21 +@end
  22 +
  23 +@implementation CNLiveLocationManager
  24 +
  25 +static CNLiveLocationManager *_manager = nil;
  26 +/// 单例初始化
  27 ++ (CNLiveLocationManager *)instance {
  28 +
  29 + static dispatch_once_t onceToken;
  30 + dispatch_once(&onceToken, ^{
  31 + _manager = [[CNLiveLocationManager alloc] init];
  32 + });
  33 + return _manager;
  34 +}
  35 +
  36 +/// 初始化
  37 +- (instancetype)init {
  38 + self = [super init];
  39 + if (self) {
  40 +
  41 + _locationManager = [[CLLocationManager alloc] init];
  42 + _locationManager.delegate = self;
  43 + _locationManager.desiredAccuracy = kCLLocationAccuracyBest;//精度
  44 + _locationManager.distanceFilter = 10;
  45 +
  46 + // 兼容iOS8.0版本
  47 + /* Info.plist里面加上2项中的一项
  48 + NSLocationAlwaysUsageDescription String YES
  49 + NSLocationWhenInUseUsageDescription String YES
  50 + */
  51 + if ([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
  52 + // iOS8.0以上,使用应用程序期间允许访问位置数据
  53 + [_locationManager requestWhenInUseAuthorization];
  54 + // iOS8.0以上,始终允许访问位置信息
  55 + // [_locationManager requestAlwaysAuthorization];
  56 + }
  57 +
  58 + _geocoder = [[CLGeocoder alloc] init];
  59 + }
  60 + return self;
  61 +}
  62 +
  63 +/// 释放
  64 ++(void)attempDealloc {
  65 +
  66 + _manager = nil;
  67 +}
  68 +
  69 +#pragma mark - 定位方法
  70 +/// 定位回调实现
  71 +- (void)getLocation:(LocationCoordinate2DBlock)coordinate2DBlock failure:(Failure)failure {
  72 + if ([CLLocationManager locationServicesEnabled] == NO) {
  73 + return;
  74 + }
  75 + _coordinate2DBlock = coordinate2DBlock;
  76 + _failure = failure;
  77 + // 停止上一次定位
  78 + [_locationManager stopUpdatingLocation];
  79 + // 开始新一次定位
  80 + [_locationManager startUpdatingLocation];
  81 +}
  82 +/// 停止定位实现
  83 +- (void)stop {
  84 + [_locationManager stopUpdatingLocation];
  85 +}
  86 +
  87 +/// 反向坐标获取地址信息实现
  88 +- (void)getLocationWithCoordinate2D:(CLLocationCoordinate2D)coordinate2D placemarkBlock:(CNLivePlacemarkBlock)placemarkBlock failure:(Failure)failure{
  89 + CLLocation *location = [[CLLocation alloc] initWithLatitude:coordinate2D.latitude longitude:coordinate2D.longitude];
  90 +
  91 + [_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
  92 +
  93 + if (!error) {
  94 + if (placemarks.count > 0) {
  95 + CLPlacemark *placemark = placemarks.lastObject;
  96 + CNLivePlacemark *livePlacemark = [CNLivePlacemark initWithCLPlacemark:placemark];
  97 + if (placemarkBlock) {
  98 + placemarkBlock(livePlacemark);
  99 + }
  100 + }else {
  101 + if (failure) {
  102 + failure(error);
  103 + }
  104 + }
  105 + }else{
  106 + if (failure) {
  107 + failure(error);
  108 + }
  109 + }
  110 + }];
  111 +}
  112 +
  113 +/// 地理编码获取经纬度实现
  114 +- (void)getLocationWithAddress:(NSString *)address coordinate2DBlock:(LocationCoordinate2DBlock)coordinate2DBlock failure:(Failure)failure {
  115 + [_geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
  116 +
  117 + if (!error) {
  118 + if (placemarks.count > 0) {
  119 + CLPlacemark *placemark = placemarks.lastObject;
  120 + if (coordinate2DBlock) {
  121 + coordinate2DBlock(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
  122 + }
  123 + }else {
  124 + if (failure) {
  125 + failure(error);
  126 + }
  127 + }
  128 + }else{
  129 + if (failure) {
  130 + failure(error);
  131 + }
  132 + }
  133 + }];
  134 +}
  135 +
  136 +#pragma mark -
  137 +#pragma mark - CLLocationManagerDelegate
  138 +- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
  139 + CLLocation *location = locations.lastObject;
  140 + CLLocationDegrees lat = location.coordinate.latitude;
  141 + CLLocationDegrees lng = location.coordinate.longitude;
  142 + NSLog(@"当前更新位置: 纬度: (%lf), 经度: (%lf)", lat, lng);
  143 +
  144 + if (_coordinate2DBlock) {
  145 + _coordinate2DBlock(lat, lng);
  146 + }
  147 +}
  148 +
  149 +- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
  150 +
  151 + if (error.code == kCLErrorDenied) {
  152 + NSLog(@"访问被拒绝");
  153 + } else if (error.code == kCLErrorLocationUnknown) {
  154 + NSLog(@"无法获取位置信息");
  155 + }
  156 + if (_failure) {
  157 + _failure(error);
  158 + }
  159 +
  160 +}
  161 +
  162 +#pragma mark - 定位实例方法
  163 +/// 定位回调
  164 ++ (void)getLocation:(LocationCoordinate2DBlock)coordinate2DBlock failure:(Failure)failure{
  165 + [[CNLiveLocationManager instance] getLocation:coordinate2DBlock failure:failure];
  166 +}
  167 +
  168 +/// 停止定位
  169 ++ (void)stop{
  170 + [[CNLiveLocationManager instance] stop];
  171 +}
  172 +
  173 +/// 是否启用定位服务
  174 ++ (BOOL)locationServicesEnabled{
  175 + return [CLLocationManager locationServicesEnabled];
  176 +}
  177 +
  178 +/// 反向地理编码获取地址信息
  179 ++ (void)getLocationWithLatitude:(NSString *)latitude longitude:(NSString *)longitude placemarkBlock:(CNLivePlacemarkBlock)placemarkBlock failure:(Failure)failure{
  180 + CLLocationCoordinate2D coordinate2D = CLLocationCoordinate2DMake([latitude doubleValue], [longitude doubleValue]);
  181 + [[CNLiveLocationManager instance] getLocationWithCoordinate2D:coordinate2D placemarkBlock:placemarkBlock failure:failure];
  182 +
  183 +}
  184 +
  185 +/// 反向地理编码获取地址信息
  186 ++ (void)getLocationWithCoordinate2D:(CLLocationCoordinate2D)coordinate2D PlacemarkBlock:(CNLivePlacemarkBlock)placemarkBlock failure:(Failure)failure{
  187 + [[CNLiveLocationManager instance] getLocationWithCoordinate2D:coordinate2D placemarkBlock:placemarkBlock failure:failure];
  188 +}
  189 +
  190 +/// 地理编码获取经纬度
  191 ++ (void)getLocationWithAddress:(NSString *)address coordinate2DBlock:(LocationCoordinate2DBlock)coordinate2DBlock failure:(Failure)failure{
  192 + [[CNLiveLocationManager instance] getLocationWithAddress:address coordinate2DBlock:coordinate2DBlock failure:failure];
  193 +}
  194 +
  195 +
  196 +@end
  197 +
  198 +@implementation CNLivePlacemark
  199 +
  200 +- (id)mutableCopyWithZone:(NSZone *)zone {
  201 + CNLivePlacemark *copy = [[[self class] allocWithZone:zone] init];
  202 + _country = [self.country mutableCopy];
  203 + _province = [self.province mutableCopy];
  204 + _city = [self.city mutableCopy];
  205 + _county = [self.county mutableCopy];
  206 + _address = [self.address mutableCopy];
  207 + _placemarkId = self.placemarkId;
  208 + _type = [self.type mutableCopy];
  209 + return copy;
  210 +}
  211 +
  212 +- (id)copyWithZone:(NSZone *)zone {
  213 + CNLivePlacemark *copy = [[[self class] allocWithZone:zone] init];
  214 + _country = [self.country copy];
  215 + _province = [self.province copy];
  216 + _city = [self.city copy];
  217 + _county = [self.county copy];
  218 + _address = [self.address copy];
  219 + _placemarkId = self.placemarkId;
  220 + _type = [self.type copy];
  221 + return copy;
  222 +}
  223 +
  224 +- (NSString *)city {
  225 + NSString *cityName = _city;
  226 + if ([cityName hasSuffix:@"市辖区"]) {
  227 + cityName = [cityName substringToIndex:[cityName length] - 3];
  228 + }
  229 + if ([cityName hasSuffix:@"市"]) {
  230 +// cityName = [cityName substringToIndex:[cityName length]];
  231 + cityName = cityName;
  232 + }
  233 + if ([cityName isEqualToString:@"香港特別行政區"] || [cityName isEqualToString:@"香港特别行政区"]) {
  234 + cityName = @"香港";
  235 + }
  236 + if ([cityName isEqualToString:@"澳門特別行政區"] || [cityName isEqualToString:@"澳门特别行政区"]) {
  237 + cityName = @"澳门";
  238 + }
  239 + return cityName;
  240 +}
  241 +
  242 +- (NSString *)province {
  243 + NSString *provinceName = _province;
  244 + if ([provinceName hasSuffix:@"省"]) {
  245 + provinceName = [provinceName substringToIndex:[provinceName length] - 1];
  246 + } else if ([provinceName hasSuffix:@"市"]) {
  247 +// provinceName = [provinceName substringToIndex:[provinceName length] - 1];
  248 + provinceName = provinceName;
  249 + }
  250 + return provinceName;
  251 +}
  252 +
  253 +/// 实例化
  254 ++ (CNLivePlacemark *)initWithCLPlacemark:(CLPlacemark *)placemark {
  255 + CNLivePlacemark *mark = [[CNLivePlacemark alloc] init];
  256 + mark.country = placemark.country ? placemark.country : @"";
  257 + mark.province = placemark.administrativeArea ? placemark.administrativeArea : @"";
  258 + mark.city = placemark.locality ? placemark.locality : mark.province;
  259 + mark.county = placemark.subLocality ? placemark.subLocality : @"";
  260 + NSString *formatAddress = [NSString stringWithFormat:@"%@%@", placemark.thoroughfare ? placemark.thoroughfare : @"",
  261 + placemark.subThoroughfare ? placemark.subThoroughfare:@""];
  262 + mark.address = formatAddress;
  263 + return mark;
  264 +}
  265 +
  266 +/// 取得省市
  267 +- (NSString *)getProvinceAndCity {
  268 + NSString *provinceName = _province ? : @"";
  269 + NSString *cityName = _city ? : @"";
  270 + if ([self.city isEqualToString:self.province]) {
  271 + provinceName = @"";
  272 + }
  273 + if ([cityName hasSuffix:@"市辖区"]) {
  274 + cityName = [cityName substringToIndex:[cityName length] - 3];
  275 + }
  276 + if ([cityName isEqualToString:@"香港特別行政區"] || [cityName isEqualToString:@"香港特别行政区"]) {
  277 + cityName = @"香港";
  278 + }
  279 + if ([cityName isEqualToString:@"澳門特別行政區"] || [cityName isEqualToString:@"澳门特别行政区"]) {
  280 + cityName = @"澳门";
  281 + }
  282 + return [provinceName stringByAppendingString:cityName];
  283 +}
  284 +
  285 +
  286 +
  287 +@end
  288 +
Example/CNLiveLocationManager.xcodeproj/project.pbxproj
@@ -247,6 +247,9 @@ @@ -247,6 +247,9 @@
247 LastUpgradeCheck = 0720; 247 LastUpgradeCheck = 0720;
248 ORGANIZATIONNAME = jyyjkt; 248 ORGANIZATIONNAME = jyyjkt;
249 TargetAttributes = { 249 TargetAttributes = {
  250 + 6003F589195388D20070C39A = {
  251 + DevelopmentTeam = 94X49GG3ZW;
  252 + };
250 6003F5AD195388D20070C39A = { 253 6003F5AD195388D20070C39A = {
251 TestTargetID = 6003F589195388D20070C39A; 254 TestTargetID = 6003F589195388D20070C39A;
252 }; 255 };
@@ -494,6 +497,7 @@ @@ -494,6 +497,7 @@
494 baseConfigurationReference = 8A786FAC06F8B380961784F9 /* Pods-CNLiveLocationManager_Example.debug.xcconfig */; 497 baseConfigurationReference = 8A786FAC06F8B380961784F9 /* Pods-CNLiveLocationManager_Example.debug.xcconfig */;
495 buildSettings = { 498 buildSettings = {
496 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 499 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  500 + DEVELOPMENT_TEAM = 94X49GG3ZW;
497 GCC_PRECOMPILE_PREFIX_HEADER = YES; 501 GCC_PRECOMPILE_PREFIX_HEADER = YES;
498 GCC_PREFIX_HEADER = "CNLiveLocationManager/CNLiveLocationManager-Prefix.pch"; 502 GCC_PREFIX_HEADER = "CNLiveLocationManager/CNLiveLocationManager-Prefix.pch";
499 INFOPLIST_FILE = "CNLiveLocationManager/CNLiveLocationManager-Info.plist"; 503 INFOPLIST_FILE = "CNLiveLocationManager/CNLiveLocationManager-Info.plist";
@@ -509,6 +513,7 @@ @@ -509,6 +513,7 @@
509 baseConfigurationReference = A14F0ED2D3E6BFCAB696AB07 /* Pods-CNLiveLocationManager_Example.release.xcconfig */; 513 baseConfigurationReference = A14F0ED2D3E6BFCAB696AB07 /* Pods-CNLiveLocationManager_Example.release.xcconfig */;
510 buildSettings = { 514 buildSettings = {
511 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 515 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  516 + DEVELOPMENT_TEAM = 94X49GG3ZW;
512 GCC_PRECOMPILE_PREFIX_HEADER = YES; 517 GCC_PRECOMPILE_PREFIX_HEADER = YES;
513 GCC_PREFIX_HEADER = "CNLiveLocationManager/CNLiveLocationManager-Prefix.pch"; 518 GCC_PREFIX_HEADER = "CNLiveLocationManager/CNLiveLocationManager-Prefix.pch";
514 INFOPLIST_FILE = "CNLiveLocationManager/CNLiveLocationManager-Info.plist"; 519 INFOPLIST_FILE = "CNLiveLocationManager/CNLiveLocationManager-Info.plist";