这里主要介绍CoreLocation的使用:
导入框架
导入主头文件
#import
CoreLocation框架中所有数据类型的前缀都是CL
CoreLocation中使用CLLocationManager对象来做用户定位
代码应用:
#import "ViewController.h"
#import
@interface ViewController ()
/**
* 定位管理者
*/
@property (nonatomic ,strong) CLLocationManager *mgr;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 成为CoreLocation管理者的代理监听获取到的位置
self.mgr.delegate = self;
// 设置多久获取一次
// self.mgr.distanceFilter = 500;
// 设置获取位置的精确度
/*
kCLLocationAccuracyBestForNavigation 最佳导航
kCLLocationAccuracyBest; 最精准
kCLLocationAccuracyNearestTenMeters; 10米
kCLLocationAccuracyHundredMeters; 百米
kCLLocationAccuracyKilometer; 千米
kCLLocationAccuracyThreeKilometers; 3千米
*/
// self.mgr.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
/*
注意: iOS7只要开始定位, 系统就会自动要求用户对你的应用程序授权. 但是从iOS8开始, 想要定位必须先"自己""主动"要求用户授权
在iOS8中不仅仅要主动请求授权, 而且必须再info.plist文件中配置一项属性才能弹出授权窗口
NSLocationWhenInUseDescription,允许在前台获取GPS的描述
NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述
*/
// 判断是否是iOS8
if([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0)
{
NSLog(@"是iOS8");
// 主动要求用户对我们的程序授权, 授权状态改变就会通知代理
//
[self.mgr requestAlwaysAuthorization]; // 请求前台和后台定位权限
// [self.mgr requestWhenInUseAuthorization];// 请求前台定位权限
}else
{
NSLog(@"是iOS7");
// 3.开始监听(开始获取位置)
[self.mgr startUpdatingLocation];
}
}
/**
* 授权状态发生改变时调用
*
* @param manager 触发事件的对象
* @param status 当前授权的状态
*/
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
/*
用户从未选择过权限
kCLAuthorizationStatusNotDetermined
无法使用定位服务,该状态用户无法改变
kCLAuthorizationStatusRestricted
用户拒绝该应用使用定位服务,或是定位服务总开关处于关闭状态
kCLAuthorizationStatusDenied
已经授权(废弃)
kCLAuthorizationStatusAuthorized
用户允许该程序无论何时都可以使用地理信息
kCLAuthorizationStatusAuthorizedAlways
用户同意程序在可见时使用地理位置
kCLAuthorizationStatusAuthorizedWhenInUse
*/
if (status == kCLAuthorizationStatusNotDetermined) {
NSLog(@"等待用户授权");
}else if (status == kCLAuthorizationStatusAuthorizedAlways ||
status == kCLAuthorizationStatusAuthorizedWhenInUse)
{
NSLog(@"授权成功");
// 开始定位
[self.mgr startUpdatingLocation];
}else
{
NSLog(@"授权失败");
}
}
#pragma mark - CLLocationManagerDelegate
//- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
/**
* 获取到位置信息之后就会调用(调用频率非常高)
*
* @param manager 触发事件的对象
* @param locations 获取到的位置
*/
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"%s", __func__);
// 如果只需要获取一次, 可以获取到位置之后就停止
// [self.mgr stopUpdatingLocation];
// 1.获取最后一次的位置
/*
location.coordinate; 坐标, 包含经纬度
location.altitude; 设备海拔高度 单位是米
location.course; 设置前进方向 0表示北 90东 180南 270西
location.horizontalAccuracy; 水平精准度
location.verticalAccuracy; 垂直精准度
location.timestamp; 定位信息返回的时间
location.speed; 设备移动速度 单位是米/秒, 适用于行车速度而不太适用于不行
*/
/*
可以设置模拟器模拟速度
bicycle ride 骑车移动
run 跑动
freeway drive 高速公路驾车
*/
CLLocation *location = [locations lastObject];
NSLog(@"%f, %f speed = %f", location.coordinate.latitude , location.coordinate.longitude, location.speed);
}
#pragma mark - 懒加载
- (CLLocationManager *)mgr
{
if (!_mgr) {
_mgr = [[CLLocationManager alloc] init];
}
return _mgr;
}
@end
记得要再info.plist中配置下面两者选一
NSLocationWhenInUseDescription,允许在前台获取GPS的描述
NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述
后面说明随便写
获取用户角度:
#pragma mark - CLLocationManagerDelegate
// 当获取到用户方向时就会调用
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
// NSLog(@"%s", __func__);
/*
magneticHeading 设备与磁北的相对角度
trueHeading 设置与真北的相对角度, 必须和定位一起使用, iOS需要设置的位置来计算真北
真北始终指向地理北极点
*/
// NSLog(@"%f", newHeading.magneticHeading);
// 将获取到的角度转为弧度 = (角度 * π) / 180;
CGFloat angle = newHeading.magneticHeading * M_PI / 180;
// 如果需要根据角度来旋转图片,如指南针等,可以这样调用
/*
顺时针 正
逆时针 负数
*/
// compasspointer为图片
self.compasspointer.transform = CGAffineTransformMakeRotation(-angle);
}
// 创建中心点
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(40.058501, 116.304171);
// c创建圆形区域, 指定区域中心点的经纬度, 以及半径
CLCircularRegion *circular = [[CLCircularRegion alloc] initWithCenter:center radius:500 identifier:@"北京"];
[self.mgr startMonitoringForRegion:circular];
区域检测回调:
// 进入监听区域时调用
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(@"进入监听区域时调用");
}
// 离开监听区域时调用
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(@"离开监听区域时调用");
}
// 根据传入的地址获取该地址对应的经纬度信息
CLGeocoder *geocoder = [[CLGeocoder alloc] init] NSString *addressStr = [[NSString alloc ]initWithString:@"北京"];
[geocoder geocodeAddressString:addressStr completionHandler:^(NSArray *placemarks, NSError *error) {
if (placemarks.count == 0 || error != nil) { return ; }
// placemarks地标数组, 地标数组中存放着地标, 每一个地标包含了该位置的经纬度以及城市/区域/国家代码/邮编等等...
// 获取数组中的第一个地标 CLPlacemark *placemark = [placemarks firstObject];
// for (CLPlacemark *placemark in placemarks) {
// NSLog(@"%@ %@ %f %f", placemark.name, placemark.addressDictionary, placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
self.latitudeLabel.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
self.longitudeLabel.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
NSArray *address = placemark.addressDictionary[@"FormattedAddressLines"];
NSMutableString *strM = [NSMutableString string]; for (NSString *str in address) { [strM appendString:str]; } NSLog(@"%@",strM); }];
反地理编码:
// 根据用户输入的经纬度创建CLLocation对象
CLLocation *location = [[CLLocation alloc] initWithLatitude:[latitude doubleValue] longitude:[longtitude doubleValue]];
// 根据CLLocation对象获取对应的地标信息
[self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark *placemark in placemarks) {
NSLog(@"%@ %@ %f %f", placemark.name, placemark.addressDictionary, placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
self.reverseDetailAddressLabel.text = placemark.locality;
}
}];
#import "ViewController.h"
#import "INTULocationManager.h"
#import
@interface ViewController ()
@property (nonatomic, strong) CLLocationManager *mgr;
@end
@implementation ViewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 1.创建位置管理者
INTULocationManager *mgr = [INTULocationManager sharedInstance];
// 2.利用位置管理者获取位置
[mgr requestLocationWithDesiredAccuracy:INTULocationAccuracyRoom timeout:5 delayUntilAuthorized:YES block:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {
if (status == INTULocationStatusSuccess) {
NSLog(@"获取位置成功 %f %f", currentLocation.coordinate.latitude , currentLocation.coordinate.longitude);
}else if(status == INTULocationStatusError)
{
NSLog(@"获取失败");
}
}];
}
@end
注意:INTULocationManager如果在8.0以后使用也需要在info.plist中配置