iOS开发 -- CoreLocation实现定位

来源:互联网 发布:最新轰炸手机短信软件 编辑:程序博客网 时间:2024/05/01 23:54

前言:

最近做的项目需要通过定位来获取当前所在位置的县一级的地名,由于没有用到地图,就选择iOS自带框架CoreLocation来实现。期间也有遇到一些问题,这里也会和大家分享,以后如果有人遇到同样的问题就可以解决了。

CoreLocation介绍

在iOS中通过Core Location框架进行定位操作。Core Location自身可以单独使用,和地图开发框架MapKit完全是独立的。在CoreLocation中主要包含了定位、地理编码(包括反编码)功能。
使用CoreLoaction中CLLocationManager类实现定位功能,首先看一下这个类的一些主要方法和属性:

类方法+ (BOOL)locationServicesEnabled;是否启用定位服务+ (CLAuthorizationStatus)authorizationStatus;定位服务授权状态,返回枚举类型:

属性desiredAccuracy定位精度,枚举类型:distanceFilter位置信息更新最小距离,
只有移动大于这个距离
才更新位置信息,默认
为kCLDistanceFilterNone:
不进行距离限制

对象方法startUpdatingLocation开始定位追踪,开始定位后将按照用户设置的更新频率执行-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;方法反馈定位信息stopUpdatingLocation停止定位追踪startUpdatingHeading开始导航方向追踪stopUpdatingHeading停止导航方向追踪startMonitoringForRegion:开始对某个区域进行定位追踪,开始对某个区域进行定位后。如果用户进入或者走出某个区域会调用- (void)locationManager:(CLLocationManager *)manager
    didEnterRegion:(CLRegion *)region和- (void)locationManager:(CLLocationManager *)manager
    didExitRegion:(CLRegion *)region代理方法反馈相关信息stopMonitoringForRegion:停止对某个区域进行定位追踪requestWhenInUseAuthorization请求获得应用使用时的定位服务授权,注意使用此方法前在要在info.plist中配置NSLocationWhenInUseUsageDescriptionrequestAlwaysAuthorization请求获得应用一直使用定位服务授权,注意使用此方法前要在info.plist中配置NSLocationAlwaysUsageDescription

CLLocationManagerDelegate代理方法-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations;位置发生改变后执行(第一次定位到某个位置之后也会执行-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading导航方向发生变化后执行-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region进入某个区域之后执行-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region走出某个区域之后执行

地理编码

除了提供位置跟踪功能之外,在定位服务中还包含CLGeocoder类用于处理地理编码和逆地理编码。

地理编码:根据地名确定坐标 - (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;

逆地理编码:根据坐标确定地名 - (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;

使用步骤

1.引入#import <CoreLocation/CoreLocation.h> 并创建定位管理对象self.locationManager = [[CLLocationManager alloc]init]; 和地理编码对象self.geocoder = [[CLGeocoder alloc]init];

2.遵循协议CLLocationManagerDelegate,设置代理

3.实现代理方法-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations获取经纬度再由逆地理编码获取地名。

遇到的问题

刚才上边说道在这期间遇到了问题,就是遵循协议,设置代理之后实现协议方法,还是不能定位,后来发现要在info.plist文件做一些配置NSLocationWhenInUseUsageDescription(前台) 、 NSLocationAlwaysUsageDescription (后台)两个均为Boolean类型值为YES,


代码:

#import "ViewController.h"#import <CoreLocation/CoreLocation.h>@interface ViewController ()<CLLocationManagerDelegate>@property(nonatomic,strong)CLLocationManager *locationManager;@property(nonatomic,strong)CLGeocoder *geocoder;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    //初始化定位管理器    self.locationManager = [[CLLocationManager alloc]init];    if (![CLLocationManager locationServicesEnabled]) {        NSLog(@"定位服务可能未打开");        return;    }            [_locationManager startUpdatingLocation];    //如果没有授权就请求用户授权    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {        [_locationManager requestWhenInUseAuthorization];    }else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse){        //设置代理        _locationManager.delegate = self;        //设置精确度        _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;        //定位频率,每隔多少米定位一次        CLLocationDistance distance = 10.0; // 十米一次        _locationManager.distanceFilter = distance;            //启动跟踪定位        [_locationManager startUpdatingLocation]; }    //地理编码:根据地名获取坐标    self.geocoder = [[CLGeocoder alloc]init];    [self getCoordinateByAddress:@"威县"];        // Do any additional setup after loading the view, typically from a nib.}#pragma mark -- 代理方法-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{    //取出数组第一个位置    CLLocation *location = [locations firstObject];    CLLocationCoordinate2D coordinate = location.coordinate;    NSLog(@"经度 = %f,纬度 =  %f ",coordinate.longitude,coordinate.latitude);     [self getAddressByLatitude:coordinate.latitude longitude:coordinate.longitude];}#pragma mark -- 地理编码(根据地名确定坐标)-(void)getCoordinateByAddress:(NSString *)address{        [self.geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {        CLPlacemark *placemark = [placemarks firstObject];        //位置        CLLocation *location = placemark.location;        //区域        CLRegion *region = placemark.region;        //详细信息        NSDictionary *addressDic = placemark.addressDictionary;       // NSLog(@"location = %@,region = %@,dict =%@",location,region,addressDic);    }];    }#pragma mark -- 逆地理编码 (根据坐标取得地名)-(void)getAddressByLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude{        CLLocation *location = [[CLLocation alloc]initWithLatitude:latitude longitude:longitude];    [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {        CLPlacemark *placemark = placemarks.firstObject;        NSLog(@"%@,%@",placemark.locality , placemark.subLocality);    }];    }


0 0
原创粉丝点击