ios 定位 航向检测
1 // ViewController.m 2 // CoreLocation框架的基本使用—定位 3 // 注意 点: 1.设置地位可用 2. 设置允许本程序定位(对弹出的框,允许即可) 3. 为模拟器 设置位置移动方式, 比如 Freeway Drive(自由驾车模式)
4 5 6 #import "ViewController.h" 7 #import <CoreLocation/CoreLocation.h> 8 9 #define isIOS(version) ([[UIDevice currentDevice].systemVersion floatValue] >= version) 10 11 @interface ViewController ()<CLLocationManagerDelegate> 12 { 13 CLLocation *_lastLoc; 14 } 15 /** 位置管理者*/ 16 @property (nonatomic, strong) CLLocationManager *locM; 17 18 @end 19 20 @implementation ViewController 21 22 #pragma mark - 懒加载 23 /** locM属性的懒加载 */ 24 -(CLLocationManager *)locM 25 { 26 if (!_locM) { 27 // 1. 创建位置管理者 28 _locM = [[CLLocationManager alloc] init]; 29 // 1.1 block , 代理, 通知 30 _locM.delegate = self; 31 32 // 精确度越高, 越好点, 而且, 定位时间越长 33 // 精确度 34 _locM.desiredAccuracy = kCLLocationAccuracyBest; 35 36 37 /** ----------iOS8.0+定位适配-------------- */ 38 39 // 如果两个授权请求,同时发送, 那么先执行第一个 40 41 if(isIOS(8.0)) 42 { 43 44 // 请求前后台定位授权 45 // 无论是在前台还是后台, 都可以获取用户位置,而且不会出现蓝条 46 // 无论是否勾选后台模式 47 // 如果当前的授权状态 != 用户未选择状态, 那么这个方法不会有效 48 // 如果当前授权状态 == 前台定位授权时, 这个方法也会有效 49 // [_locM requestAlwaysAuthorization]; 50 51 52 // 请求前台定位授权 53 // 在前台授权下, 默认只能在前台获取用户位置信息, 如果想要在后台获取用户位置, 那么 勾选后台模式 Location updates (会出现蓝条) 54 // 如果当前的授权状态 != 用户未选择状态, 那么这个方法不会有效 55 [_locM requestWhenInUseAuthorization]; 56 57 58 // 在前台授权下, 默认只能在前台获取用户位置信息, 如果想要在后台获取用户位置, 那么 勾选后台模式 Location updates (会出现蓝条), 需要额外的设置一下属性为YES 59 if (isIOS(9.0)) { 60 // _locM.allowsBackgroundLocationUpdates = YES; 61 } 62 63 64 } 65 66 67 } 68 return _locM; 69 } 70 71 72 73 74 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 75 { 76 77 // 2. 开始更新用户位置 78 // start 开始某个服务 stop 停止某个服务 79 // 一旦我们调用了这个方法, 那么就会在后台不断的获取用户位置, 然后告诉外界 80 // 标准化定位(gps/ 基站 / WiFi) 81 // 82 [self.locM startUpdatingLocation]; 83 84 85 // 显著位置变化(基站)(要求设备必须由电话模块) 86 // 当app 被杀死时也可以接收到位置通知(app -- 后台 ) 87 // [self.locM startMonitoringSignificantLocationChanges]; 88 89 90 /** 91 * ———————————应用场景————————————— 92 1) 如果要求定位及时,精度较高,并且运行时间较短,可使用标准定位; 93 2) 如果长时间监控用户位置,用户移动速度比较快(例如打车软件),可使用后者 94 * 95 */ 96 97 /** 98 * extern const CLLocationAccuracy kCLLocationAccuracyBest; 99 extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters; 100 extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters; 101 extern const CLLocationAccuracy kCLLocationAccuracyKilometer; 102 extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;ß 103 */ 104 105 // [self.locM requestLocation]; 106 107 108 109 } 110 111 112 #pragma mark - CLLocationManagerDelegate 113 114 /** 115 * 获取到位置信息时调用 116 * 117 * @param manager 位置管理者 118 * @param locations 位置数组 119 */ 120 -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 121 { 122 // NSLog(@"获取到位置"); 123 124 CLLocation *loc = [locations lastObject]; 125 126 127 NSLog(@"%lf",loc.horizontalAccuracy); 128 // 代表当前位置 horizontalAccuracy>0 才是有效的 129 if(loc.horizontalAccuracy > 0) 130 { 131 132 /** 133 * CLLocation 134 * coordinate : 经纬度 135 altitude :海拔 136 course : 航向 137 speed : 速度 138 distanceFromLocation : 计算两个点之间的直线物理距离 139 */ 140 141 /** 142 * 场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离, 143 例如:”北偏东 30度 方向,移动了 8米 ” 144 */ 145 146 // 确定航向 147 NSString *angleStr = nil; 148 switch ((int)loc.course / 90) { 149 case 0: 150 angleStr = @"北偏东"; 151 break; 152 case 1: 153 angleStr = @"东偏南"; 154 break; 155 case 2: 156 angleStr = @"南偏西"; 157 break; 158 case 3: 159 angleStr = @"西偏北"; 160 break; 161 162 default: 163 angleStr = @"掉沟里去了"; 164 break; 165 } 166 167 // 确定偏离角度 168 int angle = 0; 169 angle = (int)loc.course % 90; 170 // 正方向 171 if (angle == 0) { 172 angleStr = [angleStr substringToIndex:1]; 173 } 174 175 176 // 移动了多少 177 CLLocationDistance distance = 0; 178 if (_lastLoc) { 179 distance = [loc distanceFromLocation:_lastLoc]; 180 } 181 _lastLoc = loc; 182 183 // 拼串 184 // 例如:”北偏东 30度 方向,移动了 8米 ” 185 186 NSString *str ; 187 if (angle == 0) { 188 str = [NSString stringWithFormat:@"正%@方向, 移动了%f米", angleStr, distance]; 189 }else 190 { 191 str = [NSString stringWithFormat:@"%@%zd度方向, 移动了%f米", angleStr , angle, distance]; 192 } 193 194 195 196 NSLog(@"%@", str); 197 198 } 199 200 // 如果我们想要定位一次 201 202 // 停止位置更新 203 // [manager stopUpdatingLocation]; 204 } 205 206 /** 207 * 当前授权状态发生变化时调用 208 * 209 * @param manager 位置管理者 210 * @param status 状态 211 */ 212 -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status 213 { 214 switch (status) { 215 case kCLAuthorizationStatusNotDetermined: 216 { 217 NSLog(@"用户未选择"); 218 break; 219 } 220 case kCLAuthorizationStatusRestricted: 221 { 222 NSLog(@"受限制"); 223 break; 224 } 225 case kCLAuthorizationStatusDenied: 226 { 227 228 // 确定当前设备, 是否支持定位,或者定位服务是否开启 229 if([CLLocationManager locationServicesEnabled]) 230 { 231 NSLog(@"拒绝"); 232 233 // 我们可以调用代码, 打开设置界面 234 NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; 235 if ([[UIApplication sharedApplication] canOpenURL:url]) { 236 [[UIApplication sharedApplication] openURL:url]; 237 } 238 239 240 }else 241 { 242 NSLog(@"服务关闭"); 243 } 244 245 break; 246 } 247 case kCLAuthorizationStatusAuthorizedAlways: 248 { 249 NSLog(@"前后台定位授权"); 250 break; 251 } 252 case kCLAuthorizationStatusAuthorizedWhenInUse: 253 { 254 NSLog(@"前台定位授权"); 255 break; 256 } 257 258 259 default: 260 break; 261 } 262 } 263 264 /** 265 * 定位失败 266 * 267 * @param manager 位置管理者 268 * @param error 错误 269 */ 270 -(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error 271 { 272 NSLog(@"fail%@",error); 273 274 } 275 276 @end