IOS收藏

ios定位功能的实现

2016-03-10  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读