美文网首页IOS收藏
ios定位功能的实现

ios定位功能的实现

作者: 闯先生的猫 | 来源:发表于2016-03-10 14:58 被阅读413次

    学习定位,首先要了解它的含义,了解它的具体实现方法:下面介绍具体介绍它。
    一:介绍
    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

    相关文章

      网友评论

        本文标题:ios定位功能的实现

        本文链接:https://www.haomeiwen.com/subject/ggytlttx.html