iOS开发-CoreLocation地图基本知识示例

可先建项目直接运行学习

info.plist文件设置:


CoreLocation.png

模拟器模拟运动场景:


5FFFC80F-43EA-4728-9648-7E9CB54EE0B2.png

.m文件代码

//
//  ViewController.m
//  CoreLocation
//
//  Created by admin on 17/2/21.
//  Copyright © 2017年 zengchunjun. All rights reserved.
//

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>


#define IOS7_Later [[UIDevice currentDevice].systemVersion floatValue] >= 7.0
#define IOS8_Later [[UIDevice currentDevice].systemVersion floatValue] >= 8.0
#define IOS9_Later [[UIDevice currentDevice].systemVersion floatValue] >= 9.0
#define IOS10_Later [[UIDevice currentDevice].systemVersion floatValue] >= 10.0

@interface ViewController ()<CLLocationManagerDelegate>

@property (nonatomic,strong)CLLocationManager *locationManager;

@property (nonatomic,strong)CLLocation *lastLoc;

@end

@implementation ViewController


- (CLLocationManager *)locationManager
{
    if (_locationManager == nil) {
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.delegate = self;
        
        // 如果是ios8.0以后, 在想请求用户的位置信息, 需要主动的请求授权
        
        // 使用时授权
        [_locationManager requestWhenInUseAuthorization];
        
        // 前后台定位授权
//        [_locationManager requestAlwaysAuthorization];
        // 如果当前的授权状态是前后台定位授权, 那么默认情况下, 就可以在后台获取用户位置信息, 不需要勾选后台模式location updates
        
        // 使用时授权 + 勾选后台模式location  updates
//        [_locationManager requestWhenInUseAuthorization];
        // 效果 在后台确实可以获取到位置信息, 但是屏幕上方会出现一个蓝色的横幅, 不断提醒用户, 当前APP 正在使用你的位置
        // 对于这个在后台使用定位的方式,在iOS 9之后需要加一句代码
//        _locationManager.allowsBackgroundLocationUpdates = YES;
        
        
    }
    
    // 设置过滤距离
    // 每隔100米定位一次
    // 1 111KM/100M
    // 如果最新的位置距离上一次的位置之间的物理距离, 大于这个值, 就会通过代理来告诉我们最新的位置数据
    _locationManager.distanceFilter = 10;
    
    
    // 定位精确度
    //         kCLLocationAccuracyBestForNavigation // 最适合导航
    //         kCLLocationAccuracyBest; // 最好的
    //         kCLLocationAccuracyNearestTenMeters; // 附近10米
    //         kCLLocationAccuracyHundredMeters; // 附近100米
    //         kCLLocationAccuracyKilometer; // 附近1000米
    //         kCLLocationAccuracyThreeKilometers; // 附近3000米
    // 经验: 如果定位的精确度越高, 那么越耗电, 而且定位时间越长
    //
    _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    
    return _locationManager;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 标准定位服务 (gps/wifi/蓝牙/基站)
    [self.locationManager startUpdatingLocation];
    
    //  不能与 startUpdatingLocation同时使用
    // 必须实现代理的定位失败的方法 iOS 9以后的方法
//    [self.locationManager requestLocation];
    
    // 显著位置变化的服务(基站进行定位, 电话模块)
//    [self.locationManager startMonitoringSignificantLocationChanges];
    
    
    if ([CLLocationManager headingAvailable]) {// 判断 "磁力计"传感器 是否可用
        
        [self.locationManager startUpdatingHeading];
        
    }else
    {
        NSLog(@"当前磁力计设备不可用");
    }
    
    
    // CLLocation属性详解
    // coordinate: 经纬度信息
    // altitude: 海拔信息
    // horizontalAccuracy: 如果整个数字是负数, 就代表位置数据无效
    // verticalAccuracy:  如果整个数字是负数, 就代表海拔数据无效
    // course: 航向
    // speed: 速度
    // distanceFromLocation: 计算两个经纬度坐标之间的物理指向距离
    // 计算两点之间的距离
    CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:21.123 longitude:121.345];
    CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:22.123 longitude:121.345];
    CLLocationDistance distance = [loc1 distanceFromLocation:loc2];
    NSLog(@"%.2f",distance);
    
    
}


#pragma mark CLLocationManagerDelegate
// 检查磁力计朝向
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    // 1. 拿到当前设备朝向
    /// 0- 359.9 角度
    
    CLLocationDirection angle = newHeading.magneticHeading;
    
    // 1.1 把角度转换成为弧度
    CGFloat hudu = (angle / 180 * M_PI);
    
    
    // 2. 反向旋转图片(弧度)
//    UIView.animateWithDuration(0.5) {
//        self.compassView.transform = CGAffineTransformMakeRotation(-hudu)
//    }
    [UIView animateWithDuration:0.5 animations:^{
        
    }];
}
// 位置信息改变
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    NSLog(@"获取到位置信息");
    CLLocation *newLocation = locations.lastObject;
//    guard let newLocation = locations.last else {return}
    if (newLocation.horizontalAccuracy < 0)  return;
    // CLLocation
    // coordinate: 经纬度信息
    // altitude: 海拔信息
    // horizontalAccuracy: 如果整个数字是负数, 就代表位置数据无效
    // verticalAccuracy:  如果整个数字是负数, 就代表海拔数据无效
    // course: 航向
    // speed: 速度
    // distanceFromLocation: 计算两个经纬度坐标之间的物理指向距离
    
    //        场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离,
    //        例如:”北偏东 30度 方向,移动了 8米”
    
    // 1. 获取当前的行走航向
    NSArray *angleStrs = @[@"北偏东", @"东偏南", @"南偏西", @"西偏北"];
    int index = (int)(newLocation.course) / 90;
    NSString *angleStr = angleStrs[index];
    
    
    // 2. 行走的偏离角度
    int angle = (int)(newLocation.course) % 90;
    
    if (angle == 0) {
        
        angleStr = [@"正" stringByAppendingString:[angleStr substringToIndex:1]];
    }
    
    
    // 3. 移动了多少米
    CLLocation *lastLocation = _lastLoc ? _lastLoc : newLocation;
    CLLocationDistance distance = [newLocation distanceFromLocation:lastLocation];
    _lastLoc = newLocation;
    
    // 4. 合并字符串, 打印
    //        例如:”北偏东 30度 方向,移动了 8米”
    if (angle == 0) {
//        print(angleStr + "方向, 移动了\(distance)米")
        NSLog(@"%@",[NSString stringWithFormat:@"%@方向,移动了%.2f米",angleStr,distance]);
    }else
    {
//        print(angleStr + "\(angle)" + "方向, 移动了\(distance)米")
        NSLog(@"%@",[NSString stringWithFormat:@"%@%d方向,移动了%.2f米",angleStr,angle,distance]);
    }

}

// 定位失败
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"定位失败");
}

// 授权状态改变
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
//    kCLAuthorizationStatusNotDetermined = 0,
//    
//    kCLAuthorizationStatusRestricted,
//    
//    kCLAuthorizationStatusDenied,
//    
//    kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(10_12, 8_0),
//    
//    kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),
//
//    kCLAuthorizationStatusAuthorized
    
    switch (status) {
            
    case kCLAuthorizationStatusNotDetermined:
            printf("用户没有决定");
            break;
    case kCLAuthorizationStatusRestricted:
            printf("受限制");
            break;
    case kCLAuthorizationStatusAuthorizedWhenInUse:
            printf("前台定位授权");
            break;
    case kCLAuthorizationStatusAuthorizedAlways:
            printf("前后台定位授权");
            break;
    case kCLAuthorizationStatusDenied:
        //            print("拒绝")
        // 判断当前设备是否支持定位, 并且定位服务是否开启
        if ([CLLocationManager locationServicesEnabled]) {
            printf("真正被拒绝");
            // 手动通过代码, 来跳转到设置界面
            if (IOS8_Later) {
                
                NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                if ([[UIApplication sharedApplication] canOpenURL:url]) {
                    [[UIApplication sharedApplication] openURL:url options:@{UIApplicationOpenURLOptionUniversalLinksOnly:@""} completionHandler:nil];
                }
            }
            
            
        }else {
            // 当我们在app内部想要访问用户位置, 但是当前的定位服务是关闭状态, 那么系统会自动弹出一个窗口, 快捷跳转到设置界面, 让用户设置
            printf("定位服务应该打开");
        }
            break;
    default:
            printf("none");
            break;
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

demo分享链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容