您的位置:首页 > 移动开发 > IOS开发

iOS开发 -- CoreLocation实现定位

2016-04-22 11:50 633 查看

前言:

最近做的项目需要通过定位来获取当前所在位置的县一级的地名,由于没有用到地图,就选择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中配置NSLocationWhenInUseUsageDescription
requestAlwaysAuthorization请求获得应用一直使用定位服务授权,注意使用此方法前要在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;
/
4000
/设置精确度
_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);
}];

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息