本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正。


本文相关目录:

================== 所属文集:【iOS】07 设备工具 ==================

7.4 定位服务->1.0 简介

7.4 定位服务->2.1.1 定位 - 官方框架CoreLocation: 请求用户授权

7.4 定位服务->2.1.2 定位 - 官方框架CoreLocation: CLLocationManager位置管理器

7.4 定位服务->2.1.3.1 定位 - 官方框架CoreLocation 功能1:地理定位

7.4 定位服务->2.1.3.2 定位 - 官方框架CoreLocation 功能2:地理编码和反地理编码

7.4 定位服务->2.1.3.3 定位 - 官方框架CoreLocation 功能3:区域监听

7.4 定位服务->2.1.4 定位 - 官方框架CoreLocation 案例:指南针效果

7.4 定位服务->2.2 定位 - locationManager框架

7.4 定位服务->3.1 地图框架MapKit 功能1:地图展示

7.4 定位服务->3.2 地图框架MapKit 功能2:路线规划(导航)

7.4 定位服务->3.3 地图框架MapKit 功能3:3D视图

7.4 定位服务->3.4 地图框架MapKit 功能4:地图截图

7.4 定位服务->3.5 地图框架MapKit 功能5:POI检索

================== 所属文集:【iOS】07 设备工具 ==================


定位目录:

官方框架CoreLocation目录:

本文目录:


1.0 简介


2.0 属性方法

CLLocationCoordinate2D:是一个用来表示经纬度的结构体

关于经纬度:

distanceFilter:每隔多少米定位一次

desiredAccuracy:设置定位精确度


3.0 requestLocation:单次定位请求,获取一次位置信息


4.0 两种定位服务

4.1 标准定位服务

下面介绍下 CLLocation 对象:

CLLocation 对象属性方法:

主要方法:distanceFromLocation

4.2 显著位置变化的定位服务


代码示例:根据以上知识写一个"单次定位"的 demo

编译环境:Xcode 8.0

模拟器版本:iOS 10

Swift版本:3.0

【OC语言】
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h> @interface ViewController () <CLLocationManagerDelegate> // 代理
@property(nonatomic, strong) CLLocationManager *locationM; // 位置管理者
@end @implementation ViewController #pragma mark - 懒加载对象,并在懒加载方法中进行部分初始化操作
- (CLLocationManager *)locationM {
    if (!_locationM) {
        // 1. 创建位置管理者(需要强引用,否则一出现就会消失)强引用后,UI控件创建时会添加到subviews数组里,作用域结束时也不会释放
        _locationM = [[CLLocationManager alloc] init];
        
        // 2. 设置代理, 接收位置数据(其他方式:block、通知)
        _locationM.delegate = self;
        
        // 3. 请求用户授权 --- ios8之后才有(配置info.plist文件)
        
        //方法1:判断系统版本
        if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0){
            
            [_locationM requestAlwaysAuthorization];    //持续授权
            //[_locationM requestWhenInUseAuthorization];      //使用期间授权
        }
        
        //方法2:
        /*
         if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
         
         [_locationM requestAlwaysAuthorization];//持续授权
         [_locationM requestWhenInUseAuthorization];//使用期间授权
         }
         */
        
        // 4. 设置定位的过滤距离(单位:米), 表示用户位置移动了x米时调用对应的代理方法
        // 本次定位 与 上次定位 位置之间的物理距离 > 下面设置的数值时,就会通过代理,将当前位置告诉外界
        _locationM.distanceFilter = 500; //在用户位置改变500米时调用一次代理方法
        
        // 5. 设置定位的精确度 (单位:米),(定位精确度越高, 越耗电, 定位的速度越慢)
        // _locationM.desiredAccuracy = 100; // 当用户在100米范围内,系统会默认将100米范围内都当作一个位置
        _locationM.desiredAccuracy = kCLLocationAccuracyBest;
    }
    return _locationM;
} - (void)viewDidLoad {
    [super viewDidLoad];
} #pragma mark - 点击屏幕,开始更新用户位置
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    [self compareDistance]; //比较两点间的距离
    
    // 判断定位服务是否开启
    if ([CLLocationManager locationServicesEnabled]) {
        NSLog(@"已经开启定位服务,即将开始定位..."); #pragma mark - 开始定位
        // 方法1:标准定位服务(使用位置管理器进行定位)
        // 开始更新位置信息(一旦调用了这个方法, 就会不断的刷新用户位置,然后告诉外界)
        // 以下代码默认只能在前台获取用户的位置信息,如果想要在后台获取用户的位置信息, 那么需要勾选后台模式 location updates
        // 小经验: 如果以后使用位置管理者这个对象, 实现某个服务,可以用startXX开始某个服务,stopXX停止某个服务
        // [self.locationM startUpdatingLocation];
        
        // 方法2:监听重大位置变化的服务(基于基站进行定位)(显著位置变化定位服务)
        //  [self.locationM startMonitoringSignificantLocationChanges];
        
        // 单次定位请求
        // 必须实现代理的定位失败方法
        // 不能与startUpdatingLocation方法同时使用
        [self.locationM requestLocation];
    } else {
        NSLog(@"没有开启定位服务");
    }
} #pragma mark - 比较两点间的距离(直线距离)
- (void)compareDistance {
    // 北京位置
    CLLocation *location1 = [[CLLocation alloc] initWithLatitude:39.26 longitude:115.25];
    // 上海位置
    CLLocation *location2 =[[CLLocation alloc] initWithLatitude:30.4 longitude:120.51];
    
    // 两个地方的距离(单位:米)
    CGFloat distance = [location2 distanceFromLocation:location1];
    
    NSLog(@"比较两个点的距离:%f", distance / 1000);
} #pragma mark - 代理方法:当位置管理器获取到用户位置后,就会调用此方法
// 参数: (manager:位置管理者) (locations: 位置对象数组)
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    
    NSLog(@"位置信息:%@", locations);
    
    // 停止定位(代理方法一直调用,会非常耗电,除非特殊需求,如导航)
    // 只想获取一次用户位置信息,那么在获取到位置信息之后,停止更新用户的位置信息
    // 应用场景: 获取用户所在城市
    [manager stopUpdatingLocation];
} -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    NSLog(@"定位失败");
} #pragma mark - 代理方法:当用户授权状态发生变化时调用
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
    
    switch (status) {
            
        case kCLAuthorizationStatusNotDetermined:{
            NSLog(@"1.用户还未决定");
            break;
        }
        case kCLAuthorizationStatusRestricted:{
            NSLog(@"2.访问受限(苹果预留选项,暂时没用)");
            break;
        }
            // 定位关闭时 and 对此APP授权为never时调用
        case kCLAuthorizationStatusDenied:{
            // 定位是否可用(是否支持定位或者定位是否开启)
            if([CLLocationManager locationServicesEnabled]){
                NSLog(@"3.定位服务是开启状态,需要手动授权,即将跳转设置界面");
                // 在此处, 应该提醒用户给此应用授权, 并跳转到"设置"界面让用户进行授权在iOS8.0之后跳转到"设置"界面代码
                NSURL *settingURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                
                if([[UIApplication sharedApplication] canOpenURL:settingURL]){
                    
                    //  [[UIApplication sharedApplication] openURL:settingURL]; // 方法过期
                    
                    [[UIApplication sharedApplication]openURL:settingURL options:nil completionHandler:^(BOOL success) {
                        NSLog(@"已经成功跳转到设置界面");
                    }];
                }
                else{
                    NSLog(@"定位关闭,不可用");
                }
                break;
            }
        case kCLAuthorizationStatusAuthorizedAlways:{
            NSLog(@"4.获取前后台定位授权");
            break;
        }
        case kCLAuthorizationStatusAuthorizedWhenInUse:{
            NSLog(@"5.获得前台定位授权");
            break;
        }
        default:
            break;
        }
    }
} -(void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
} @end

打印结果:

OC - 单次定位[11287:835597] 比较两个点的距离:1093.824596
OC - 单次定位[11287:835597] 已经开启定位服务,即将开始定位...
OC - 单次定位[11287:835597] 3.定位服务是开启状态,需要手动授权,即将跳转设置界面
OC - 单次定位[11287:835597] 已经成功跳转到设置界面
OC - 单次定位[11287:835597] 5.获得前台定位授权
OC - 单次定位[11287:835597] 4.获取前后台定位授权
OC - 单次定位[11287:835597] 位置信息:("<+39.78583000,+116.40641700> +/- 5.00m (speed -1.00 mps / course -1.00) @ 2016/9/21 \U4e2d\U56fd\U6807\U51c6\U65f6\U95f4 \U4e0b\U53485:19:01")
【Swift 语言】
import UIKit
import CoreLocation class ViewController: UIViewController {
    
    // MARK: - 懒加载
    lazy var locationM : CLLocationManager = {
        
        // 1. 创建位置管理者(需要强引用,否则一出现就会消失)强引用后,UI控件创建时会添加到subviews数组里,作用域结束时也不会释放
        let locationM : CLLocationManager = CLLocationManager()
        
        // 2. 设置代理, 接收位置数据(其他方式:block、通知)
        locationM.delegate = self
        
        // 3. 请求用户授权 --- ios8之后才有(配置info.plist文件)
        // 判断系统版本
        if (Float(UIDevice.current.systemVersion)! >= 8.0){
            locationM.requestAlwaysAuthorization()// 前后台定位授权
            // locationM.requestWhenInUseAuthorization()  // 前台定位授权
        }
        
        // 4. 设置过滤距离
        // 如果当前位置, 距离上一次的位置之间的物理距离大于以下数值时, 就会通过代理, 将当前位置告诉外界
        locationM.distanceFilter = 100   // 每隔100 米定位一次
        
        // 5. 设置定位的精确度(定位精确度越高, 越耗电, 定位的速度越慢)
        locationM.desiredAccuracy = kCLLocationAccuracyBest
        
        return locationM
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    // MARK: - 点击屏幕,开始更新用户位置
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        // 方法1:标准定位服务(使用位置管理器进行定位)
        // 开始更新位置信息(一旦调用了这个方法, 就会不断的刷新用户位置, 然后告诉外界)
        // 以下代码默认只能在前台获取用户的位置信息, 如果想要在后台获取用户的位置信息, 那么需要勾选后台模式 location updates
        // 小经验: 如果以后使用位置管理者这个对象, 实现某个服务, 可以用startXX开始某个服务,stopXX停止某个服务
        // locationM.startUpdatingLocation()
        
        // 方法2:监听重大位置变化的服务(基于基站进行定位)(显著位置变化定位服务)
        // locationManager.startMonitoringSignificantLocationChanges()
        
        // 单次定位请求
        // 必须实现代理的定位失败方法
        // 不能与startUpdatingLocation方法同时使用
        locationM.requestLocation()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
} // 类扩展(CLLocationManager的代理方法)
extension ViewController: CLLocationManagerDelegate {
    
    // 代理方法:当位置管理器获取到用户位置后,就会调用此方法
    // 参数: (manager:位置管理者) (locations: 位置对象数组)
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
        print("位置信息:%@", locations)
        
        // 停止定位(代理方法一直调用,会非常耗电,除非特殊需求,如导航)
        // 只想获取一次用户位置信息,那么在获取到位置信息之后,停止更新用户的位置信息
        // 应用场景: 获取用户所在城市
        manager.stopUpdatingLocation()
    }     func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("定位失败--\(error.localizedDescription)")
    }
    
    // 代理方法:当用户的定位授权状态发生变化时调用
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        
        switch status {
            
        case CLAuthorizationStatus.notDetermined:
            print("1.用户还未决定定")
        case CLAuthorizationStatus.restricted:
            print("2.访问受限(苹果预留选项,暂时没用)")
        // 定位关闭时 and 对此APP授权为never时调用
        case CLAuthorizationStatus.denied:
            // 定位是否可用(是否支持定位或者定位是否开启)
            if (CLLocationManager.locationServicesEnabled()){
                print("3.定位服务是开启状态,需要手动授权,即将跳转设置界面")
                
                // 在此处, 应该提醒用户给此应用授权, 并跳转到"设置"界面让用户进行授权在iOS8.0之后跳转到"设置"界面代码
                var settingURL:URL?
                
                if (Float(UIDevice.current.systemVersion)! >= 8.0){
                    settingURL = URL(string: UIApplicationOpenSettingsURLString)
                }else{
                    // 设置app scheme
                    settingURL = URL(string: "prefs:root=LOCATION_SERVICES")
                }
                
                if (UIApplication.shared.canOpenURL(settingURL!)){
                    UIApplication.shared.openURL(settingURL!)
                    print("已经成功跳转到设置界面")
                }
            }else{
                print("定位关闭,不可用")
            }
        case CLAuthorizationStatus.authorizedAlways:
            print("4.获取前后台定位授权")
        case CLAuthorizationStatus.authorizedWhenInUse:
            print("5.获得前台定位授权")
        }
    }
}

打印结果:

3.定位服务是开启状态,需要手动授权,即将跳转设置界面
已经成功跳转到设置界面
5.获得前台定位授权
4.获取前后台定位授权
位置信息:%@ [<+39.78583000,+116.40641700> +/- 5.00m (speed -1.00 mps / course -1.00) @ 2016/9/21 中国标准时间 下午5:59:01]

本文源码 Demo 详见 Github

https://github.com/shorfng/iOS_7.0_Device-Tools


作者:蓝田(Loto)
【作品发布平台】

简书

博客园

Gitbook(如果觉得文章太长,请阅读此平台发布的文章)

【代码托管平台】

Github

【如有疑问,请通过以下方式交流】

评论区回复

发送邮件shorfng@126.com

本文版权归作者和本网站共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
  • 支付宝扫一扫 向我打赏

  • 你也可以微信 向我打赏

【iOS】7.4 定位服务->2.1.2 定位 - 官方框架CoreLocation: CLLocationManager(位置管理器)的更多相关文章

  1. 【iOS】7.4 定位服务->2.1.1 定位 - 官方框架CoreLocation: 请求用户授权

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...

  2. 【iOS】7.4 定位服务->2.1.3.1 定位 - 官方框架CoreLocation 功能1:地理定位

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...

  3. 【iOS】7.4 定位服务->2.1.3.2 定位 - 官方框架CoreLocation 功能2:地理编码和反地理编码

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...

  4. 【iOS】7.4 定位服务->2.1.3.3 定位 - 官方框架CoreLocation 功能3:区域监听

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...

  5. 【iOS】7.4 定位服务->2.1.4 定位 - 官方框架CoreLocation 案例:指南针效果

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...

  6. 【iOS】7.4 定位服务->3.1 地图框架MapKit 功能1:地图展示

    > 本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. --- > 本文相关目录: ================== 所属文集:[[ ...

  7. 【iOS】7.4 定位服务->3.2 地图框架MapKit 功能2:路线规划(导航)

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...

  8. 【iOS】7.4 定位服务->3.3 地图框架MapKit 功能3:3D视图

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...

  9. 【iOS】7.4 定位服务->3.4 地图框架MapKit 功能4:地图截图

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...

随机推荐

  1. Spring IO Platform简介及示例

    什么是Spring IO Platform Spring IO Platform,简单的可以认为是一个依赖维护平台,该平台将相关依赖汇聚到一起,针对每个依赖,都提供了一个版本号: 这些版本对应的依赖都 ...

  2. 抓取QQ空间相册

    某天,想下载某人的相册,发现一张一张下载,工作量巨大,所以写了这个工具. 使用到的工具 Fiddler(抓包工具) python(脚本语言) intellij 步骤 分析包 获取相册分类链接信息 打开 ...

  3. Codeforces374A

    A. Inna and Pink Pony time limit per test1 second memory limit per test 256 megabytes input standard ...

  4. RedisRepository分享和纠错

    .mytitle { background: #2B6695; color: white; font-family: "微软雅黑", "宋体", "黑 ...

  5. C++ 头文件系列(iosfwd)

    简介 输入输出历来都是语言的重要部分,在C++中,该库也是占据了相当大的一部分. C++的输入输出库是其遵循面向对象设计的结果,并结合了泛型编程. 以下是这些库类的关系图(箭头标示继承,白框表示摸板, ...

  6. 用label实现自适应宽度的方法

  7. 关于JavaScript中的escape、encodeURI和encodeURIComponent

    此文内容与关于JavaScript中的编码和解码函数 关联 escape() 方法: 采用ISO Latin字符集对指定的字符串进行编码.所有的空格符.标点符号.特殊字符以及其他非ASCII字符都将被 ...

  8. JAVA高级编程序——JDBC(连接mysql数据库)——(一)

    java要想连接数据库,就要用JDBC(java database connection),用这个jar包 (mysql-connector-java-xxx-xx-bin.jar) sun公司为我们 ...

  9. matlab分割背景与物体

    [name,path]=uigetfile('*.jpg;*.png;*.bmp','选择一张图片');f=imread([path name]);count = 0; T = mean2(f); d ...

  10. PPT中翻书动画的制作

    一.新建一个空白的PowerPoint文档.   二.制作两个页面:   1.点击“自选图形”右边的小三角,选择“基本图形”下的“折角形”图形,在PowerPoint中画出一个书页样的图形,宽度最好小 ...