oc之定位CllocationManage类

#import <CoreLocation/CoreLocation.h>

class <CLLocationManagerDelegate>

{ 

  CLLocationManager * locationManager;

     NSString * currentCity; //当前城市

}

 

#pragma mark -定位

- (void)locate {

    //判断定位功能是否打开

    if ([CLLocationManager locationServicesEnabled]) {

        locationManager = [[CLLocationManager alloc] init];

        locationManager.delegate = self;

        //        [locationManager requestAlwaysAuthorization];

        currentCity = [[NSString alloc] init];

        [locationManager startUpdatingLocation];

    }

    

}

 

#pragma mark CoreLocation delegate

 

//定位失败则执行此代理方法

//定位失败弹出提示框,点击"打开定位"按钮,会打开系统的设置,提示打开定位服务

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {

    UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"允许\"定位\"提示" message:@"请在设置中打开定位" preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction * ok = [UIAlertAction actionWithTitle:@"打开定位" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

        //打开定位设置

        NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];

        [[UIApplication sharedApplication] openURL:settingsURL];

    }];

    UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {

        

    }];

    [alertVC addAction:cancel];

    [alertVC addAction:ok];

    [self presentViewController:alertVC animated:YES completion:nil];

    

}

//定位成功

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {

    [locationManager stopUpdatingLocation];

    CLLocation *currentLocation = [locations lastObject];

    CLGeocoder * geoCoder = [[CLGeocoder alloc] init];

    

    //反编码

    [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {

        if (placemarks.count > 0) {

            CLPlacemark *placeMark = placemarks[0];

            currentCity = placeMark.locality;

            if (!currentCity) {

                currentCity = nil;

            }

            NSLog(@"%@",currentCity); //这就是当前的城市

            NSLog(@"%@",placeMark.name);//具体地址:  xx市xx区xx街道

        }

        else if (error == nil && placemarks.count == 0) {

            NSLog(@"No location and error return");

            currentCity = nil;

        }

        else if (error) {

            NSLog(@"location error: %@ ",error);

            currentCity = nil;

        }

        

    }];

}

 

 

 

 

 

IOS 之 Core Loaction 定位服务与地图

https://blog.csdn.net/samrtian/article/details/14087233

使用CLLoactionManager类之前得加入 CoreLocation框架

 

然后加入头文件 

 

#import<CoreLocation/CoreLocation.h>

 

#import<CoreLocation/CLLocationManagerDelegate>

 

 

接着定义变量

 

CLLocationManager* location;

 

_location = [[CLLocationManageralloc]init];

 

_location.delegate =self;  

 

_location.desiredAccuracy =kCLLocationAccuracyBest; //设置精确度到M  精确越大越耗电

 

_location.distanceFilter = 1000.0f; //多少距离侦测一次

 

[_locationstartUpdatingLocation]; //开始侦测

 

[_location stopUpdatingLocation]; //停止侦测

 

 

//委托方法  

 

//更新方法

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

{

    CLLocation* lo = [locations lastObject];

    _pointX.text = [NSString stringWithFormat:@"%g", lo.coordinate.longitude];

    _pointY.text = [NSString stringWithFormat:@"%g", lo.coordinate.latitude];

    

    CLGeocoder *geocoder = [CLGeocoder new];

    [geocoder reverseGeocodeLocation:lo completionHandler:^(NSArray *placemarks, NSError *error) {

        if ( [placemarks count] > 0 ) {

            CLPlacemark* placemark = placemarks[0];

            NSDictionary *dictAddress = placemark.addressDictionary;

            NSString *strAddress = [dictAddress objectForKey:(NSString*)kABPersonAddressStateKey];

            self.address.text = strAddress;

            NSLog(@"地址: %@", strAddress);

        }

    }];

}

 

//失败时调用的方法

 

-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

 

 

 

CLLocation* lo; 属性

 

lo.coordinate.longitude  //精度

 

lo.coordinate.latitude  //纬度

 

lo.horizontalAccuracy  //中心圆半径.相当于地图上你看到的自己所在的一个圆圈  值越大位置越不确定 为负时就不能依赖坐标值了.

 

lo.altitude  //海平面上下多少米

 

lo.verticalAccuracy  //海拨, 为负不确定海拨

 

ClLocationDistance distance = [lo distanceFromLocation: CLLocation* lo]; //计算两个之间的距离

 

 

 

//地理信息反编码,就是把看不懂的坐标数字转换为地点的相关描述,包括国家,市,街道,很准确

 

//使用这个类取地址信息的时候还需要引入

 

#import <AddressBook/AddressBook.h>

 

CLGeocoder *geocoder = [CLGeocodernew]; //反编码类

 

CLPlacemark* placemark = placemarks[0]; //封装着地点相关信息

 

placemark.addressDictionary //地址信息的字典,包含一些键值对,在地址簿框架中

 

placemark.ISOcountryCode    //ISO国家代号

 

placemark.postalCode        //邮政编码

 

placemark.administrativeArea  //行政区域信息

 

placemark.subAdministrativeArea  //行政区域附加信息

 

placemark.locality               //指定城市信息

 

placemark.subLocality            //指定城市信息附加信息

 

placemark.thoroughfare           //指定街道级别信息

 

placemark.subThoroughfare        //指定街道级别的附加信息

 

 

 

//通过地址信息查询

 

geocodeAddressString:completionHandler:

 

 

 

//这个网址可以是地图上的一些资料也可以生成GPX文件

 

http://mygeoposition.com

 

 

 

//关于地图相关的IOS6自带的地图

 

核心视图类是MKMapView,委托协议是MKMapViewDelegate 使用时需要导入MapKit框架. 

 

#import <MapKit/MapKit.h>

 

MKMapView *mapView;

 

mapView.mapType

 

有以下几个类型

 

MKMapTypeStandard 标准地图

 

MKMapTypeStatellite 卫星地图

 

MKMapTypeHybrid  混合地图

 

mapView.showUserLocation 允许跟踪显示用户位置信息

 

setUserTrackingMode:MKUserTrackingModeFloow:animated: 设置跟踪模式 还得实现委托方法

 

MKUserTrackingModeNone 没有用户跟踪模式

 

MKUserTrackingModeFollow 可以跟踪用户的位置变化

 

MKUserTrackingModeFollowWithHeading 可以跟踪用户的位置和方向变化

 

//设置跟踪用户

-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation

{

    _mapView.centerCoordinate = userLocation.location.coordinate;

}

//添加地图标注

 

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

{

    CLLocation* lo = [locations lastObject];

    _pointX.text = [NSString stringWithFormat:@"%g", lo.coordinate.longitude];

    _pointY.text = [NSString stringWithFormat:@"%g", lo.coordinate.latitude];

    

    CLGeocoder *geocoder = [CLGeocoder new];

    [geocoder reverseGeocodeLocation:lo completionHandler:^(NSArray *placemarks, NSError *error) {

        if ( [placemarks count] > 0 ) {

            [_mapView removeAnnotations:_mapView.annotations];

            CLPlacemark* placemark = placemarks[0];

            //调整地图位置和缩放比例

            MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(placemark.location.coordinate, 10000, 10000);

            [_mapView setRegion:viewRegion animated:YES];

            LocationInfo *locationInfo = [LocationInfo new];

            locationInfo.stree = placemark.thoroughfare;

            locationInfo.coordinate = placemark.location.coordinate;

            //这个动作会触发下边委托方法

            [_mapView addAnnotation:locationInfo];

        }

    }];

}

//被上边的add动作调用最后一个参数就是上边的locationInfo,这个必须自己定义而且还得实现MKAnnotation协议

//地图类的委托方法.  用于显示地图上的标注

-(MKAnnotationView *)mapView:(MKMapView *)themapView viewForAnnotation:(id<MKAnnotation>)annotation

{

    MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:@"PIN_ANNOTATION"];

    if ( annotationView == nil ) {

        annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"PIN_ANNOTATION"];

    }

    

    annotationView.pinColor = MKPinAnnotationColorPurple; //大头针的颜色

    annotationView.animatesDrop = YES;   //设置标注视图时是否以动画效果

    annotationView.canShowCallout = YES;   //显示气泡提示信息

    

    return annotationView;

}

 

//使用程序外的苹果地图

 

需要使用MKPlacemark和MKMapItem这两个类

 

- (IBAction)query:(id)sender {

    CLLocationCoordinate2D ll2d = _sPoint.coordinate; //_sPoint是CLLoation类

    NSDictionary *address = _place.addressDictionary; //_place是 CLPlaceMark类

    MKPlacemark *place1 = [[MKPlacemark alloc] initWithCoordinate:ll2d addressDictionary:address];

    MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:place1];

    [mapItem openInMapsWithLaunchOptions:nil];

}

 

//调用谷歌WEB地图

- (IBAction)query:(id)sender {

    NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps?q=%f,%f", _sPoint.coordinate.latitude, _sPoint.coordinate.longitude];

    NSURL *url = [NSURL URLWithString:urlString];

    [[UIApplication sharedApplication] openURL:url];

}

 

来源:CSDN 

原文:https://blog.csdn.net/samrtian/article/details/14087233 

版权声明:本文为博主原创文章,转载请附上博文链接!

 

地图之CLLocationManager的使用

https://www.jianshu.com/p/ef6994767cbb

1.iOS8以前使用CLLocationManager

 

1.导入头文件 <CoreLocation/CoreLocation.h>

 

2.创建位置管理者 CLLocationManager , 并添加到属性。

3.设置代理、遵守协议、实现代理方法,在代理方法中获取位置信息

4.调用开始更新位置方法

5.设置 每隔多远定位一次 和 精确度,精确度越高越耗电,定位时间越长

 

// 1.设置位置管理者属性

@property (nonatomic, strong) CLLocationManager *lcManager;

// 2.判断是否打开了位置服务

if ([CLLocationManager locationServicesEnabled]) {

    // 创建位置管理者对象

    self.lcManager = [[CLLocationManager alloc] init];

    self.lcManager.delegate = self; // 设置代理

    // 设置定位距离过滤参数 (当本次定位和上次定位之间的距离大于或等于这个值时,调用代理方法)

    self.lcManager.distanceFilter = 100;

    self.lcManager.desiredAccuracy = kCLLocationAccuracyBest; // 设置定位精度(精度越高越耗电)

    [self.lcManager startUpdatingLocation]; // 开始更新位置

}

/** 获取到新的位置信息时调用*/

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

{

    NSLog(@"定位到了");

}

/** 不能获取位置信息时调用*/

-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

{

    NSLog(@"获取定位失败");

}

 

 

6.请求授权,iOS6之后,苹果开始加强保护用户隐私,在 Info.plist 文件中定义 Key提醒用户,提高用户允许定位的概率。

 

 

 

 

 

Info.plist 设置Key

 

 

 

7.如果要后台定位,需要打开后台模式

 

 

 

 

 

 

勾选后台模式

 

 

 

2.iOS8.0之后使用CLLocationManager

 

1.iOS8之后,苹果又进一步加强了隐私保护,不会主动填出对话框,让用户选择

2.需要实现两个方法(实现其一即可),并且 Info.plist 中设置对应的 key ,才会弹框

 

1.requestWhenInUseAuthorization

 

1.当程序当前的授权状态为未决定时,在前台时请求定位服务许可时使用。需要先在 Info.plist 文件中设置一个Key:NSLocationWhenInUseUsageDescription, 如果不设置key,系统会忽略定位请求。

 

 

 

 

 

Info.plist 设置对应的Key

 

 

2.当用户授权 when-in-use时,程序在前台时可以启动大部分定位服务。如果想要后台定位,需要开启后台定位模式,但在状态栏会出现蓝条提示用户程序正在进行定位。

 

[_lcManager requestWhenInUseAuthorization];

 

 

 

 

 

 

请求定位的弹框

 

 

 

 

 

 

后台模式下的 blue bar

 

2.requestAlwaysAuthorization

 

1.请求前后台定位服务授权,当授权状态为未决定时请求用户授权。前提是在 Info.plist 文件中包含key NSLocationAlwaysUsageDescription

 

 

 

 

 

 

 

Info.plist中 设置对应的Key

 

 

 

 

 

 

请求定位的弹框

 

3.注意

 

1.iOS8之后,如果想要定位,必须调用 requestWhenInUseAuthorization 或 requestAlwaysAuthorization方法。

2.如果两个请求授权的方法都执行了,会出现以下情况

 

1.when-in-use写在前面,第一次打开程序时请求授权,如果勾选了后台模式,进入后台会出现蓝条提示正在定位。当程序退出,第二次打开程序时 Always 会再次请求授权。之后进入后台就不会出现蓝条了(前后台都能定位)。

2.Always写在前面, when-in-use写在后面,只会在第一次打开程序时请求授权,因为 Always得到的授权大于when-in-use的到的授权

 

 

 

4.判断是否开启了定位服务

 

在启动更新位置之前要先判断是否开启了定位服务

 

if ([CLLocationManager locationServicesEnabled]) { // 判断是否打开了位置服务

        [self.lcManager startUpdatingLocation]; // 开始更新位置

    }

 

5.适配版本号的方法

 

 

when-in-use和 Always 都是iOS8之后出现的方法,如果不进行版本适配,运行在iOS7上就会crash,此时需要做版本号判断

1.判断版本号

 

if ([[UIDevice currentDevice].systemVersion floatValue] >=8.0 ) {

[_lcManager requestAlwaysAuthorization];

}

 

 

2.适配版本的另一种方法

 

if ([_lcManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {

            [_lcManager requestWhenInUseAuthorization];

        }

 

6.监听定位服务状态的改变

 

实现代理方法,判断定位服务的状态

 

/** 定位服务状态改变时调用*/

-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status

{

    switch (status) {

        case kCLAuthorizationStatusNotDetermined:

        {

            NSLog(@"用户还未决定授权");

            break;

        }

        case kCLAuthorizationStatusRestricted:

        {

            NSLog(@"访问受限");

            break;

        }

        case kCLAuthorizationStatusDenied:

        {

            // 类方法,判断是否开启定位服务

            if ([CLLocationManager locationServicesEnabled]) {

                NSLog(@"定位服务开启,被拒绝");

            } else {

                NSLog(@"定位服务关闭,不可用");

            }

            break;

        }

        case kCLAuthorizationStatusAuthorizedAlways:

        {

            NSLog(@"获得前后台授权");

            break;

        }

        case kCLAuthorizationStatusAuthorizedWhenInUse:

        {

            NSLog(@"获得前台授权");

            break;

        }

        default:

            break;

    }

}

 

7.代理方法返回的 locations 信息

 

当位置管理器,获取到位置后,调用 locationManager:didUpdateLocations:方法,返回的类型为 CLLocation 的位置信息数组,以下为数组包含的属性

 

1.coordinate : 当前位置的坐标

 

latitude : 纬度

longitude : 经度

 

 

2.altitude : 海拔,高度

3.horizontalAccuracy : 纬度和经度的精度

4.verticalAccuracy : 垂直精度(获取不到海拔时为负数)

5.course : 行进方向(真北)

6.speed : 以米/秒为单位的速度

7.description : 位置描述信息

 

 

 

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

{

    CLLocation *location = [locations firstObject];

    NSLog(@"%@", location);

}

 

3.iOS9.0之后使用CLLocationManager

 

1.iOS9.0之后有一种新的请求定位的方法 requestLocation

 

2.作用:按照定位精确度从低到高进行排序,逐个进行定位。如果获取到的位置不是精确度最高的那个,也会在定位超时后,通过代理告诉外界。

3.注意:

 

1.必须实现 ocationManager:didUpdateLocations: 和 locationManager:didFailWithError 方法,但是只调用一次

2.不能与startUpdatingLocation同时使用

 

 

 

    if ([CLLocationManager locationServicesEnabled]) { // 判断是否打开了位置服务

        [self.lcManager requestLocation];

    }

 

 

4.实现 requestWhenInUseAuthorization 或 requestAlwaysAuthorization 方法,并设置对应的 key

 

if ([[UIDevice currentDevice].systemVersion floatValue] >=8.0 ) {

     // iOS0.0:如果当前的授权状态是使用是授权,那么App退到后台后,将不能获取用户位置,即使勾选后台模式:location

    [_lcManager requestWhenInUseAuthorization];

    }

 

 

5.必须勾选后台模式,并设置 allowsBackgroundLocationUpdates 属性为YES(默认是NO)

 

1.当定位完成时,设置为NO,并且不再定位跟踪

2.使用 -responsdToSelector: 判断

 

 

 

// iOS9.0+ 要想继续获取位置,需要使用以下属性进行设置(注意勾选后台模式:location)但会出现蓝条

if ([_lcManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) {

    _lcManager.allowsBackgroundLocationUpdates = YES;

}

 

链接:https://www.jianshu.com/p/ef6994767cbb

來源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 

posted @ 2019-01-25 09:48  sundaysios  阅读(998)  评论(0编辑  收藏  举报