1.建立CoreLocation的管理者。CoreLocation要强引用git
2.实现CLLocationManagerDelegate代理。数组
3.开始或中止代理
app
#import <CoreLocation/CoreLocation.h> @interface ViewController () <CLLocationManagerDelegate> @property (nonatomic, strong)CLLocationManager *mrg; @end @implementation ViewController -(CLLocationManager *)mrg { if (_mrg == nil) { //1,建立CoreLocation的管理者 self.mrg = [[CLLocationManager alloc] init]; } return _mrg; } - (void)viewDidLoad { [super viewDidLoad]; //2,成为CoreLocation的代理 self.mrg.delegate = self; //3,开始定位 [self.mrg startUpdatingLocation]; } #pragma mark - CLLocationManagerDelegate -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"%s",__func__); //打印位置信息 /* location.coordinate; 坐标, 包含经纬度 location.altitude; 设备海拔高度 单位是米 location.course; 设置前进方向 0表示北 90东 180南 270西 location.horizontalAccuracy; 水平精准度 location.verticalAccuracy; 垂直精准度 location.timestamp; 定位信息返回的时间 location.speed; 设备移动速度 单位是米/秒, 适用于行车速度而不太适用于不行 */ CLLocation *location = [locations lastObject]; NSLog(@"%f,%f",location.coordinate.latitude,location.coordinate.longitude); // 获取到位置信息以后就会调用(调用频率很是高).若是只须要获取一次, 就要在这里设置中止 // [self.mgr stopUpdatingLocation]; }
iOS7只要开始定位, 系统就会自动要求用户对你的应用程序受权. 可是从iOS8开始, 想要定位必须先"本身""主动"要求用户受权.在iOS8中不单单要主动请求受权, 并且必须再info.plist文件中配置一项属性才能弹出受权窗口,value值能够随意写.eg:iOS7也能够添加,但不强制。框架
Privacy - Location Usage Description(iOS7)ide
NSLocationWhenInUseDescription,容许在前台获取GPS的描述动画
NSLocationAlwaysUsageDescription,容许在后台获取GPS的描述编码
if([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { NSLog(@"是iOS8"); // 主动要求用户对咱们的程序受权, 受权状态改变就会通知代理 [self.mgr requestAlwaysAuthorization]; // 请求前台和后台定位权限 // [self.mgr requestWhenInUseAuthorization]; // 请求前台定位权限 } //iOS8中须要额外添加在个代理方法 #pragma mark - CLLocationManagerDelegate - (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(@"受权失败"); } }
1.// 设置多久获取一次(单位是米,超出多米就开始调用) self.mgr.distanceFilter = 500; 2.// 设置获取位置的精确度 /* kCLLocationAccuracyBestForNavigation 最佳导航 kCLLocationAccuracyBest; 最精准 kCLLocationAccuracyNearestTenMeters; 10米 kCLLocationAccuracyHundredMeters; 百米 kCLLocationAccuracyKilometer; 公里 kCLLocationAccuracyThreeKilometers; 3公里 */ self.mgr.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
// 上一次的位置 @property (nonatomic, strong) CLLocation *previousLocation; // 总路程 @property (nonatomic, assign) CLLocationDistance sumDistance; // 总时间 @property (nonatomic, assign) NSTimeInterval sumTime; #pragma mark - CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { // 获取当前的位置 CLLocation *newLocation = [locations lastObject]; if (self.previousLocation != nil) { // 计算两次的距离(单位时米) CLLocationDistance distance = [newLocation distanceFromLocation:self.previousLocation]; // 计算两次之间的时间(单位只秒) timestamp 当前获取到为止信息的时间 NSTimeInterval dTime = [newLocation.timestamp timeIntervalSinceDate:self.previousLocation.timestamp]; // 计算速度(米/秒) CGFloat speed = distance / dTime; // 累加时间 self.sumTime += dTime; // 累加距离 self.sumDistance += distance; // 计算平均速度 CGFloat avgSpeed = self.sumDistance / self.sumTime; NSLog(@"距离%f 时间%f 速度%f 平均速度%f 总路程 %f 总时间 %f", distance, dTime, speed, avgSpeed, self.sumDistance, self.sumTime); } // 纪录上一次的位置 self.previousLocation = newLocation; }
// 1.添加指南针图片 UIImageView *iv = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"bg_compasspointer"]]; iv.center = CGPointMake(self.view.center.x, self.view.center.y); [self.view addSubview:iv]; self.compasspointer = iv; #pragma mark - CLLocationManagerDelegate // 当获取到用户方向时就会调用 - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { /* magneticHeading 设备与磁北的相对角度;trueHeading 设置与真北的相对角度 必须和定位一块儿使用, 通常使用磁北 顺时针 正 逆时针 负数 */ // 1.将获取到的角度转为弧度 = (角度 * π) / 180; CGFloat angle = newHeading.magneticHeading * M_PI / 180; // 2.旋转图片 效果很差,建议使用核心动画 self.compasspointer.transform = CGAffineTransformMakeRotation(-angle); }
- (void)viewDidLoad { [super viewDidLoad]; self.mgr.delegate = self; // 注意:若是是iOS8, 想进行区域检测, 必须本身主动请求获取用户隐私的权限.像CoreLocation的iOS8使用同样,须要在info添加权限,如NSLocationAlwaysUsageDescription if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0 ) { [self.mgr requestAlwaysAuthorization]; } // 开始检测用户所在的区域 //1.建立区域 /*CLRegion 有两个子类是专门用于指定区域的 一个能够指定蓝牙的范围CLBeaconRegion/ 一个是能够指定圆形的范围CLCircularRegion */ //建立圆形区域, 指定区域中心点的经纬度, 以及半径、标识 CLLocationCoordinate2D center = CLLocationCoordinate2DMake(40.058501, 116.304171); CLCircularRegion *circular = [[CLCircularRegion alloc] initWithCenter:center radius:500 identifier:@"软件园"]; //2.开始监听 [self.mgr startMonitoringForRegion:circular]; } #pragma mark - CLLocationManagerDelegate // 进入监听区域时调用 - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { NSLog(@"进入监听区域时调用"); } // 离开监听区域时调用 - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { NSLog(@"离开监听区域时调用"); }
这个方法只须要头文件声明#import <CoreLocation/CoreLocation.h>。而与以上方法不一样,是不须要实现代理,只须要简单实现编码对象的方法atom
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //1.建立地理编码对象 CLGeocoder *geocoder = [[CLGeocoder alloc] init]; // 2.利用地理编码对象编码 // 根据传入的地址获取该地址对应的经纬度信息 [geocoder geocodeAddressString:@"beijing" completionHandler:^(NSArray *placemarks, NSError *error) { if (placemarks.count == 0 || error != nil) { return ; } // placemarks地标数组, 地标数组中存放着地标, 每个地标包含了该位置的经纬度以及城市/区域/国家代码/邮编等等..。 for (CLPlacemark *placemark in placemarks) { NSLog(@"name:%@ addressDictionary:%@ latitude:%f longitude:%f", placemark.name, placemark.addressDictionary, placemark.location.coordinate.latitude, placemark.location.coordinate.longitude); NSArray *address = placemark.addressDictionary[@"FormattedAddressLines"]; //遍历数组,读取插入字符串 NSMutableString *strM = [NSMutableString string]; for (NSString *str in address) { [strM appendString:str]; } NSLog(@"strm:%@",strM); } }]; }
和地位编码同样,只须要简单导入头文件spa
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //1.建立地理编码对象 CLGeocoder *geocoder = [[CLGeocoder alloc] init]; CLLocation *location = [[CLLocation alloc] initWithLatitude:23.0f longitude:112.9f]; [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { for (CLPlacemark *placemark in placemarks) { NSLog(@"name:%@ \n addressDictionary:%@ \n latitude:%f \n longitude:%f \n locality:%@", placemark.name, //具体位置 placemark.addressDictionary, //地理位置详细信息 placemark.location.coordinate.latitude, //经度 placemark.location.coordinate.longitude, //纬度 placemark.locality); //城市名字 } }]; }
一样iOS8须要在info添加权限
代理
#import "INTULocationManager.h" - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 1.建立位置管理者 INTULocationManager *mgr = [INTULocationManager sharedInstance]; // 2.利用位置管理者获取位置 /* INTULocationAccuracy 精确度,包括更新的位置和时间 timeout 延时时间 status 发送状态 */ [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(@"获取失败"); } }]; }