ios定位功能的实现

学习定位,首先要了解它的含义,了解它的具体实现方法:下面介绍具体介绍它。
一:介绍
1、定位要使用CoreLocation框架
2、功能
(1)基础定位
(2)地理编码(文字转换成地理位置) 反编码(把经纬度转换成地名)
3、iOS8 iOS9之后的改变
iOS8 的改变
(1)(添加了)定位服务的目的(在Info.plist中填写)
《1》NSLocationAlwaysUsageDescription
《2》NSLocationWhenInUseUsageDescription
《3》如果忘记写就不能使用 定位功能 没有提示信息

(2)请求用户授权
<1> requestAlwaysAuthorization
<2> requestWhenInUseAuthorization
<3> 如果和描述的目的不匹配 也不能使用定位功能

iOS9的改变
iOS9 按Home键 进入后台 如果需要继续定位
<1> 在info.plist 添加 Required background modes->App registers for location updates 如果不添加这对键值 却使用后台定位功能 系统会直接崩溃
<2> allowsBackgroundLocationUpdates 需要同时设置成YES

二:使用
1、使用定位服务所需的相关类和其他数据类型
(1)CLLocationManager
定位的管理者 可以通过这个类创建定位服务的功能
(2)CLLocation:地理位置信息相关的类

(3)CLLocationCoordinate2D:经纬度(坐标)信息的一个数据类型(是一个结构体)
(4)CLRegion:表示范围的一个类
(5)CLGeocoder:地理编码 反地理编码的类
(6)CLPlacemark:表示地标的类 用文字表示位置信息的类(里面同时包含了location)
(7)CLHeading:表示导航方向的类 航向
(8)CLCircularRegion 圆形区域
(9)CLLocationDistance:距离
2、具体使用
(1)定位
<0> 检查用户是否在设置中 打开了定位服务
<1> 初始化定位对象
<2> info中添加描述使用定位的目的 并向用户申请授权
<3> 挂上代理 并实现代理方法
<4> 如果需要使用后台定位服务需要在 info中添加Required background modes 这个KEY以及它里面的元素App registers for location updates
<5> 开始定位

下面具体代码实现定位:

//  ViewController.m
//  3.7 定位
//
//  Created by 记忆 on 16/3/7.
//  Copyright © 2016年 Remeber. All rights reserved.
//

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
{
    CLLocationManager *locationManager;
    UILabel *speedLabel;
    UILabel *distanceLabel;
    UILabel *timeLabel;
    UILabel *avgSpeedLabel;
    
    CLLocation *lastLoc;//上一次更新的位置
    BOOL isFirst;//标记 是否是第一次 定位
    CLLocationDistance allDistance;//总距离
    NSTimeInterval allTime;//总时间
    
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    isFirst = YES;
    
    for (int i = 10; i<14; i++) {
        UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 100+45*(i-10), CGRectGetWidth(self.view.frame)-20, 40)];
        label.tag = i;
        label.backgroundColor = [UIColor lightGrayColor];
        label.textAlignment = NSTextAlignmentCenter;
        [self.view addSubview:label];
    }
    speedLabel = [self.view viewWithTag:10];
    distanceLabel = [self.view viewWithTag:11];
    timeLabel = [self.view viewWithTag:12];
    avgSpeedLabel = [self.view viewWithTag:13];
    
    
    
    
//    0、判断 用户是否 在《设置》里面 打开了 位置服务功能
    if (![CLLocationManager locationServicesEnabled]) {
        NSLog(@"用户打开了 位置服务功能");
        /*
//        1、跳弹出框 提示用户打开步骤
//        2、通过代码 跳出设置页面
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"请在设置中打开定位功能" preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
        }]];
        [self presentViewController:alertController animated:YES completion:nil];
        */
        
//        openURL:用于跳转app 跳到iOS允许跳到的页面
//        [[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        
        
//        判断是否可以打开 能打开就跳到设置页面
        if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]) {
            
//            跳转到 设置页面
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        };
    
        return;
    }
    
//    1、创建定位管理者的对象
    locationManager = [[CLLocationManager alloc]init];
//    多少米 去更新一次位置信息
    locationManager.distanceFilter = 10;
//    设置位置的精准度
    locationManager.desiredAccuracy = 10;
    
    
//    2、info中添加描述使用定位的目的 并向用户申请授权
    [locationManager requestWhenInUseAuthorization];
    
    
//    3、挂上代理 并实现代理方法
    locationManager.delegate = self;
    
//    4、是否使用后台定位的功能
    locationManager.allowsBackgroundLocationUpdates = YES;
    
//    5、开始定位
    [locationManager startUpdatingLocation];
    
}
//两个代理方法
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray<CLLocation *> *)locations{
//    bug -> 第一次 得到的距离 是负数 错误
//    错误原因:第一次的时候 lastLoc 是空的
//    定位代理方法的触发:
//    第一次 定位当前位置
//    第二次定位 走了100之后 再次定位
    
//    真正有效的距离是
//    1-2 2-3 ...
    
    
    
    
//    位置信息
    CLLocation *curLoc = locations.firstObject;
    
    //    解决办法
    //    跳过第一次更新 直接把第一次更新的loc赋给lastLoc

    if (isFirst == YES) {
        isFirst =NO;
        lastLoc = curLoc;
        return;
    }
    
//    坐标:经纬度 -> struct 结构体
//    latitude:纬度
//    longitude:经度
    
    CLLocationCoordinate2D coordinate = curLoc.coordinate;
    NSLog(@"经度:%f 纬度:%f",coordinate.longitude,coordinate.latitude);
    
//    cllocationDistance -> double
    NSLog(@"高度:%f",curLoc.altitude);
    
//    可以通过水平精准度 来判断是否定位成功
//    如果是负数 表示 定位错误
    NSLog(@"水平精准度%f",curLoc.altitude);
    NSLog(@"垂直精准度:%f",curLoc.verticalAccuracy);
    
    /*
     course当前设备前进的方向
     0°表示向北
     90°表示向东
     180°表示向南
     270°表示向西
     */
    NSLog(@"航向:%f",curLoc.course);
//    当前行驶速度
    NSLog(@"速度:%f",curLoc.speed);
    
//    floor 楼层的高度 -> level 几层
    NSLog(@"%ld",curLoc.floor.level);
    
//    当前定位的日期NSData
    NSLog(@"当前的定位日期:%@",curLoc.timestamp);
    
    
//    1、是否超速
//    speed > 要求的速度
    speedLabel.text = curLoc.speed>=30 ? [NSString stringWithFormat:@"您已超速 当前速度%0.1f",curLoc.speed]:@"您在安全驾驶";
    

    
    
//    3、行驶距离
//    总距离 = 每一次更新位置得到的距离累加
//     更新位置得到的距离=上一次的loc 和当期的loc
//     CLLocationDistance ->double
//     得到两次loc之间的距离方法:
//    - (CLLocationDistance)getDistanceFrom:(const CLLocation *)location
    
    //得到两次更新 位置信息 之间的距离
    CLLocationDistance distance = [curLoc distanceFromLocation:lastLoc];
    NSLog(@"两次之间的距离:%f",distance);
    
    allDistance += distance;
    distanceLabel.text = [NSString stringWithFormat:@"您总共行驶了%0.1f米",allDistance];
    
//
//    4、行驶时间
//     总时间 = 每一次更新 得到的时间间隔的累加
//     可以得到当期的时间戳
//     日期有一个方法 计算两个日期之间的时间间隔
//     
//    - (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate
//    ?上一次时间 -> 通过记录 上一次更新的location来得到
    
     allTime += [curLoc.timestamp timeIntervalSinceDate:lastLoc.timestamp];
    int hours = allTime/3600;
    int min = (int)allTime%3600/60;
    int sec = (int)allTime%3600%60;
    
    timeLabel.text = [NSString stringWithFormat:@"您行驶了%d时%d分%d秒",hours,min,sec];
    
    //    2、平均速度
    //    总距离/总时间
    avgSpeedLabel.text = [NSString stringWithFormat:@"平均速度每秒%0.1f",allDistance/allTime];
    
    // 将要出 定位的代理方法的时候 curLoc没有用了
    // 把curLoc 变成了 上一次的 位置信息
    // 赋给 lastLoc
    lastLoc = curLoc;
    
}
- (void)locationManager:(CLLocationManager *)manager
       didFailWithError:(NSError *)error{
    NSLog(@"error:%@",error);
    
}
22.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容