1.需要在info.plist 中进行信任设置 ,将以下信息选择性加入
//总是定位
Privacy - Location Always and When In Use Usage Description
// 当使用的时候定位
Privacy - Location When In Use Usage Description
//之后便是开始定位,因为iOS8.0之后,当APP想访问用户的隐私信息时,系统不再自动弹出一个对话框让用户授权,所以需要主动请求用户授权
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 100.0f;
if ([[[UIDevice currentDevice]systemVersion] doubleValue] >8.0){
[self.locationManager requestWhenInUseAuthorization];
}
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
_locationManager.allowsBackgroundLocationUpdates =YES;
}
[self.locationManager startUpdatingLocation];
后台定位
- 在前台定位基础上, 勾选后台模式Location updates, 并且设置以下属性为YES
if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0)
{
一个布尔值,该值指示是否应用程序想要接收位置更新时暂停。
self.locationM.allowsBackgroundLocationUpdates = YES;
}
------------代理方法--------------
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
if ([error code] == kCLErrorDenied) {
NSLog(@"访问被拒绝");
}
if ([error code] == kCLErrorLocationUnknown) {
NSLog(@"无法获取位置信息"); }
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray
CLLocation *newLocation = locations[0];
// 获取当前所在的城市名
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count > 0) {
CLPlacemark *placemark = placemarks[0];
NSString *city = placemark.locality;
if (!city) {
city = placemark.administrativeArea;
}
NSLog(@"city = %@", city);//城市名
NSLog(@"--%@",placemark.name);//街名
NSLog(@"++++%@",placemark.subLocality); //区(海淀)
NSLog(@"country == %@",placemark.country);//中国
NSLog(@"administrativeArea == %@",placemark.administrativeArea); //省
}
else if (placemarks.count == 0 && error == nil){
NSLog(@"没有结果");
}else if (error != nil){
NSLog(@"有错误");
}}];
[manager stopUpdatingLocation];
}
监听用户授权状态
表示当前应用程序的授权状态。
(CLAuthorizationStatus)status
当用户授权状态发生变化时调用
-(void)locationManager:(nonnull CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
用户还未决定
case kCLAuthorizationStatusNotDetermined:
{
NSLog(@"用户还未决定");
break;
}
访问受限(苹果预留选项,暂时没用)
case kCLAuthorizationStatusRestricted:
{
NSLog(@"访问受限");
break;
}
定位关闭时和对此APP授权为never时调用
case kCLAuthorizationStatusDenied:
{
定位是否可用(是否支持定位或者定位是否开启)
if([CLLocationManager locationServicesEnabled])
{
NSLog(@"定位开启,但被拒");
在此处, 应该提醒用户给此应用授权, 并跳转到"设置"界面让用户进行授权
在iOS8.0之后跳转到"设置"界面代码
NSURL *settingURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if([[UIApplication sharedApplication] canOpenURL:settingURL])
{
[[UIApplication sharedApplication] openURL:settingURL];
}
}else
{
NSLog(@"定位关闭,不可用");
}
break;
}
获取前后台定位授权
case kCLAuthorizationStatusAuthorizedAlways:
case kCLAuthorizationStatusAuthorized: 失效,不建议使用
{
NSLog(@"获取前后台定位授权");
break;
}
获得前台定位授权
case kCLAuthorizationStatusAuthorizedWhenInUse:
{
NSLog(@"获得前台定位授权");
break;
}
default:
break;
}
}
** 判断区域监听服务是否可用(定位服务是否关闭, 定位是否授权, 是否开启飞行模式)**
if ([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]])
{
创建区域中心
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(29.12345, 131.23456);
创建区域(指定区域中心,和区域半径)
CLLocationDistance radius = 1000;
判断区域半径是否大于最大监听区域半径,如果大于, 就没法监听
if (radius > self.locationM.maximumRegionMonitoringDistance) {
radius = self.locationM.maximumRegionMonitoringDistance;
}
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:radius identifier:@"烟火"];
开始监听指定区域
[self.locationM startMonitoringForRegion:region];}else{
NSLog(@"区域监听不可用");
}
进去监听区域后调用(调用一次)
-(void)locationManager:(nonnull CLLocationManager *)manager didEnterRegion:(nonnull CLRegion *)region{
NSLog(@"进入区域---%@", region.identifier);
[manager stopMonitoringForRegion:region];
}
离开监听区域后调用(调用一次)
-(void)locationManager:(nonnull CLLocationManager *)manager didExitRegion:(nonnull CLRegion *)region{
NSLog(@"离开区域---%@", region.identifier);
}
//获取区域状态
[self.locationM requestStateForRegion:region];
回调代理:
请求某个区域状态时, 回调的代理方法
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
switch (state) {
case CLRegionStateUnknown:
NSLog(@"未知状态");
break;
case CLRegionStateInside:
NSLog(@"在区域内部");
break;
case CLRegionStateOutside:
NSLog(@"在区域外部");
break;
default:
break;
}}