CoreLocation 的基本使用 以及定位 指南针的实现 (附加: 系统版本适配的方法,和后台更新用户位置的方法及注意)
#import "ViewController.h" #import <CoreLocation/CoreLocation.h> @interface ViewController ()<CLLocationManagerDelegate> @property(nonatomic ,strong)CLLocationManager * manager; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //设置定位管理者 CLLocationManager * manager = [[CLLocationManager alloc]init]; self.manager = manager; //设置代理 manager.delegate = self; /* kCLLocationAccuracyBestForNavigation (适合导航) kCLLocationAccuracyBest; (最好的) kCLLocationAccuracyNearestTenMeters; 附近10m kCLLocationAccuracyHundredMeters; 100m kCLLocationAccuracyKilometer; 1000m kCLLocationAccuracyThreeKilometers; 3000m */ //设置定位精度 越进准, 越耗电,定位时间越长 self.manager.desiredAccuracy = kCLLocationAccuracyBest; //每个多少米定位一次 // self.manager.distanceFilter = 100; //获取当前设备的系统等级 //第一种进行系统版本适配的方法 if( [[UIDevice currentDevice].systemVersion floatValue] >= 8.0){ //iOS8.0 之后 需要请求用户授权, 并在info 里配置对应的key //前后台定位授权 [manager requestAlwaysAuthorization]; //前台定位授权 // [manager requestWhenInUseAuthorization]; } //在iOS9.0 提供的下面的方法, 前提是一定要后台模式下勾选允许更新位置,否则报错 //第二种进行系统版本适配的方法 if ([self.manager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) { self.manager.allowsBackgroundLocationUpdates = YES; } [self test]; } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ //manager默认只在前台允许更新位置,如果需要后台更新位置, 需要在后台模式中勾选 location updates [self.manager startUpdatingLocation]; /* kCLLocationAccuracyBestForNavigation (适合导航) kCLLocationAccuracyBest; (最好的) kCLLocationAccuracyNearestTenMeters; 附近10m kCLLocationAccuracyHundredMeters; 100m kCLLocationAccuracyKilometer; 1000m kCLLocationAccuracyThreeKilometers; 3000m */ //该方法的它会根据精确度由低到高去定位, 如果定位超时,就会直接通过代理返回当前精度的位置 // [self.manager requestLocation]; //这个方法需要代理实现locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error //并且这个方法不能与startUpdatingLocation 和 allowDeferredLocationUpdates 同时使用 } //当定位成功后,更新位置就会调用 -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{ CLLocation * loc = [locations firstObject]; NSLog(@"%f , %f " , loc.coordinate.latitude , loc.coordinate.longitude); } //当授权状态发生改变是调用 -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{ } //定位失败时执行 -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ } //计算两个地点的距离 两个点的直线距离.(不是真实距离) -(void)test { //创建两个地点 CLLocation * loc1 = [[CLLocation alloc]initWithLatitude:10 longitude:119]; CLLocation * loc2 = [[CLLocation alloc]initWithLatitude:10 longitude:120]; //计算两个地点的距离 CLLocationDistance dis = [loc1 distanceFromLocation:loc2]; NSLog(@"%f" , dis); } //指南针的实现 -(void)test2 { CLLocationManager * manager = [[CLLocationManager alloc]init]; manager.delegate = self; //开始更新指向 [manager startUpdatingHeading]; } //当指向发生改变时调用 (注意 更新指向,不用获取用户授权, 因为只是更新手机的方向,不涉及用户隐私) -(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{ //磁北方向 CLLocationDirection magneticHeading = newHeading.magneticHeading; //将角度装换为弧度 CGFloat angel = magneticHeading/180 * M_PI ; //然后根据弧度 更改指南针图片的transform 注意是取弧度的负值,因为得到的磁北角度是相对磁北的角度,然后需要指南针旋转到磁北,所以是负值 }