定位功能介绍
关于定位开发一般用两种方法实现,一种使用高德百度的第三方SDK,另一种使用苹果自带的CoreLocation框架。我介绍的也只是CoreLocation框架,关于第三方的SDK介绍,大家可以参考他们提供的文档。定位时候主要使用CLLocationManager、 CLLocationManagerDelegate和CLLocation。CLLocationManager是定位服务管理类它能够给我们提供获得 设备的位置信息和高度信息,也可以监控设备进入或离开某个区域,它还可以帮助获得设备的运行方向等。CLLocationManagerDelegate 是CLLocationManager类委托协议。CLLocation类是封装了位置和高度信息。
方法实现
权限申请
在项目的 Info.plist 添加定位权限申请,其中:
iOS 8 - iOS 10 版本:
NSLocationWhenInUseUsageDescription 表示应用在前台的时候可以搜到更新的位置信息。
NSLocationAlwaysUsageDescription 申请Always权限,以便应用在前台和后台(suspend 或 terminated)都可以获取到更新的位置数据。
iOS 11 版本:
NSLocationAlwaysAndWhenInUseUsageDescription 申请Always权限,以便应用在前台和后台(suspend 或 terminated)都可以获取到更新的位置数据(NSLocationWhenInUseUsageDescription 也必须有)。
注意:如果需要同时支持在iOS8-iOS10和iOS11系统上后台定位,建议在plist文件中同时添加NSLocationWhenInUseUsageDescription、NSLocationAlwaysUsageDescription和NSLocationAlwaysAndWhenInUseUsageDescription权限申请。
在App Transport Security Settings下添加Allow Arbitrary Loads设置成Bool类型,设为YES。
代码实现
#import <CoreLocation/CoreLocation.h>//引入Corelocation框架
@interface LocationViewController ()< CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *locationManager;//设置manager
@property (nonatomic, strong) NSString *currentCity;
@end
@implementation LocationViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self locate];
}
- (void)locate {
if ([CLLocationManager locationServicesEnabled]) {//监测权限设置
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;//设置代理
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//设置精度
self.locationManager.distanceFilter = 1000.0f;//距离过滤
[self.locationManager requestAlwaysAuthorization];//位置权限申请
[self.locationManager startUpdatingLocation];//开始定位
}
}
#pragma mark location代理
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"您还未开启定位服务,是否需要开启?" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
UIAlertAction *queren = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSURL *setingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication]openURL:setingsURL];
}];
[alert addAction:cancel];
[alert addAction:queren];
[self.navigationController presentViewController:alert animated:YES completion:nil];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
[self.locationManager stopUpdatingLocation];//停止定位
//地理反编码
CLLocation *currentLocation = [locations lastObject];
CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
//当系统设置为其他语言时,可利用此方法获得中文地理名称
NSMutableArray
*userDefaultLanguages = [[NSUserDefaults standardUserDefaults]objectForKey:@"AppleLanguages"];
// 强制 成 简体中文
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"zh-hans", nil]forKey:@"AppleLanguages"];
[geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count > 0) {
CLPlacemark *placeMark = placemarks[0];
NSString *city = placeMark.locality;
if (!city) {
self.currentCity = @"⟳定位获取失败,点击重试";
} else {
self.currentCity = placeMark.locality ;//获取当前城市
}
} else if (error == nil && placemarks.count == 0 ) {
} else if (error) {
self.currentCity = @"⟳定位获取失败,点击重试";
}
// 还原Device 的语言
[[NSUserDefaults
standardUserDefaults] setObject:userDefaultLanguages
forKey:@"AppleLanguages"];
}];
}
947539-20160818142431609-2143381124.jpegCLPlacemark属性详解
其中四个直辖市中的administrativeArea(省)为nil,可根据此判断直辖市。
网友评论