美文网首页iOS 开发iOS 开发 iOS Developer
【iOS】7.4 定位服务->2.1.3.1 定位 - 官

【iOS】7.4 定位服务->2.1.3.1 定位 - 官

作者: 蓝田_Loto | 来源:发表于2016-09-23 12:50 被阅读290次

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


    本文相关目录:
    ================== 所属文集:【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目录:

    定位的功能实现:


    地理定位的步骤:


    详细讨论下步骤5

    iOS 8.0- 的定位

    勾选后台模式,图解:


    代码2:

    编译环境:Xcode 8.0
    模拟器版本:iOS 10
    Swift版本:3.0

    info.plist 文件配置.png
    【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. 创建位置管理者
            _locationM = [[CLLocationManager alloc] init];
            
            // 2. 设置代理, 接收位置数据(其他方式:block、通知)
            _locationM.delegate = self;
            
            // 3.前台定位,后台定位(在info.plist文件中配置对应的key)
            
            // 4. 设置定位的过滤距离(单位:米), 表示用户位置移动了x米时调用对应的代理方法
            _locationM.distanceFilter = 500; //在用户位置改变500米时调用一次代理方法
            
            // 5. 设置定位的精确度 (单位:米),(定位精确度越高, 越耗电, 定位的速度越慢)
            _locationM.desiredAccuracy = kCLLocationAccuracyBest;
        }
        return _locationM;
    }
    
    #pragma mark - 点击屏幕,开始更新用户位置
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        
        // 判断定位服务是否开启
        if ([CLLocationManager locationServicesEnabled]) {
            NSLog(@"已经开启定位服务,即将开始定位...");
            
    #pragma mark - 开始定位
            [self.locationM startUpdatingLocation];
        } else {
            NSLog(@"没有开启定位服务");
        }
    }
    
    #pragma mark - 代理方法:当位置管理器获取到用户位置后,就会调用此方法
    -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
        
        NSLog(@"位置信息:%@", locations);
        
        // 停止定位(代理方法一直调用,会非常耗电,除非特殊需求,如导航)
        [manager stopUpdatingLocation];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    
    【Swift语言】
    
    import UIKit
    import CoreLocation
    
    class ViewController: UIViewController {
        
        // 懒加载
        lazy var locationM : CLLocationManager = {
            
            // 1. 创建位置管理者
            let locationM : CLLocationManager = CLLocationManager()
            
            // 2. 设置代理, 接收位置数据(其他方式:block、通知)
            locationM.delegate = self
            
            // 3.前台定位,后台定位(在info.plist文件中配置对应的key)
            
            // 4. 设置过滤距离
            // 如果当前位置, 距离上一次的位置之间的物理距离大于以下数值时, 就会通过代理, 将当前位置告诉外界
            locationM.distanceFilter = 100   // 每隔100 米定位一次
            
            // 5. 设置定位的精确度(定位精确度越高, 越耗电, 定位的速度越慢)
            locationM.desiredAccuracy = kCLLocationAccuracyBest
            
            return locationM
        }()
        
        // 点击屏幕,开始更新用户位置
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            locationM.startUpdatingLocation()
        }
    }
    
    // 类扩展(CLLocationManager的代理方法)
    extension ViewController: CLLocationManagerDelegate {
            
        // 代理方法:当位置管理器,获取到位置后,就会调用此方法
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            print("获取到位置")
            
            // 只想获取一次用户位置信息,那么在获取到位置信息之后,停止更新用户的位置信息
            // 应用场景: 获取用户所在城市
            manager.stopUpdatingLocation()
        }
    }
    

    iOS 8.0+ 的定位

    代码3:

    编译环境:Xcode 8.0
    模拟器版本:iOS 10
    Swift版本:3.0

    这里只贴主要代码,其余和代码2相同,详见文末 github 地址

    info.plist 文件配置
    【OC语言】
    
    #pragma mark - 懒加载对象,并在懒加载方法中进行部分初始化操作
    - (CLLocationManager *)locationM {
        if (!_locationM) {
            // 1. 创建位置管理者
            _locationM = [[CLLocationManager alloc] init];
            
            // 2. 设置代理, 接收位置数据(其他方式:block、通知)
            _locationM.delegate = self;
            
            // 3.定位(在info.plist文件中配置对应的key)
            
            // 如果两个授权都请求,那么先执行前面那个请求弹框,后面那个请求授权 有可能 下次被调用时,才会起作用
            // 如果,先请求的是“前后台授权”,那“前台授权”即使被调用,也不会有反应(因为“前后台授权”权限大于“前台授权”)
            // 反之,如果先请求的是“前台授权”,而且用户选中的是“允许”,那下次被调用时“前后台授权”会做出请求,但只请求一次
            
            // 本质:1. 两个授权同时请求,先执行前面那个授权请求
            //      2. “前后台请求授权”方法,在(当前的授权状态 == 用户未选择状态 or 前台授权状态) 才会起作用
            //      3. “前台请求授权”方法,在(当前的授权状态 == 用户未选择状态) 才会起作用
            
            // 判断系统版本,做适配
            if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
                // 前台定位
                // 配合后台模式,屏幕上方会出现一个蓝色的横幅, 不断提醒用户, 当前APP 正在使用你的位置
                [_locationM requestWhenInUseAuthorization];
                
                // 前后台定位
                // 无论是否勾选后台模式, 都可以获取位置信息. 而且无论前后台, 都不会出现蓝条
                // [_locationM requestAlwaysAuthorization];
            }
            
            // 4. 设置定位的过滤距离(单位:米), 表示用户位置移动了x米时调用对应的代理方法
            _locationM.distanceFilter = 500; //在用户位置改变500米时调用一次代理方法
            
            // 5. 设置定位的精确度 (单位:米),(定位精确度越高, 越耗电, 定位的速度越慢)
            _locationM.desiredAccuracy = kCLLocationAccuracyBest;
        }
        return _locationM;
    }
    
    【Swift语言】
    
        // 懒加载
        lazy var locationM : CLLocationManager = {
            
            // 1. 创建位置管理者
            let locationM : CLLocationManager = CLLocationManager()
            
            // 2. 设置代理, 接收位置数据(其他方式:block、通知)
            locationM.delegate = self
            
            // 3.定位(在info.plist文件中配置对应的key)
            
            // 如果两个授权都请求,那么先执行前面那个请求弹框,后面那个请求授权 有可能 下次被调用时,才会起作用
            // 如果,先请求的是“前后台授权”,那“前台授权”即使被调用,也不会有反应(因为“前后台授权”权限大于“前台授权”)
            // 反之,如果先请求的是“前台授权”,而且用户选中的是“允许”,那下次被调用时“前后台授权”会做出请求,但只请求一次
            
            // 本质:1. 两个授权同时请求,先执行前面那个授权请求
            //      2. “前后台请求授权”方法,在(当前的授权状态 == 用户未选择状态 or 前台授权状态) 才会起作用
            //      3. “前台请求授权”方法,在(当前的授权状态 == 用户未选择状态) 才会起作用
            
            // 判断系统版本,做适配
            if (Float(UIDevice.current.systemVersion)! >= 8.0){
                // 前台定位
                // 配合后台模式,屏幕上方会出现一个蓝色的横幅, 不断提醒用户, 当前APP 正在使用你的位置
                locationM.requestWhenInUseAuthorization()
                
                // 前后台定位
                // 无论是否勾选后台模式, 都可以获取位置信息. 而且无论前后台, 都不会出现蓝条
                // locationM.requestAlwaysAuthorization()
            }
            
            // 4. 设置过滤距离
            // 如果当前位置, 距离上一次的位置之间的物理距离大于以下数值时, 就会通过代理, 将当前位置告诉外界
            locationM.distanceFilter = 100   // 每隔100 米定位一次
            
            // 5. 设置定位的精确度(定位精确度越高, 越耗电, 定位的速度越慢)
            locationM.desiredAccuracy = kCLLocationAccuracyBest
            
            return locationM
        }()
    

    iOS 9.0+ 的定位

    代码4:

    编译环境:Xcode 8.0
    模拟器版本:iOS 10
    Swift版本:3.0

    这里只贴主要代码,其余和代码2相同,详见文末 github 地址

    info.plist 文件配置
    【OC语言】
    #pragma mark - 懒加载对象,并在懒加载方法中进行部分初始化操作
    - (CLLocationManager *)locationM {
        if (!_locationM) {
            // 1. 创建位置管理者
            _locationM = [[CLLocationManager alloc] init];
            
            // 2. 设置代理, 接收位置数据(其他方式:block、通知)
            _locationM.delegate = self;
            
            // 3.定位(在info.plist文件中配置对应的key)
            
            // 如果两个授权都请求,那么先执行前面那个请求弹框,后面那个请求授权 有可能 下次被调用时,才会起作用
            // 如果,先请求的是“前后台授权”,那“前台授权”即使被调用,也不会有反应(因为“前后台授权”权限大于“前台授权”)
            // 反之,如果先请求的是“前台授权”,而且用户选中的是“允许”,那下次被调用时“前后台授权”会做出请求,但只请求一次
            
            // 本质:1. 两个授权同时请求,先执行前面那个授权请求
            //      2. “前后台请求授权”方法,在(当前的授权状态 == 用户未选择状态 or 前台授权状态) 才会起作用
            //      3. “前台请求授权”方法,在(当前的授权状态 == 用户未选择状态) 才会起作用
            
            // 判断系统版本,做适配
            if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
                // 前台定位
                // 配合后台模式,屏幕上方会出现一个蓝色的横幅, 不断提醒用户, 当前APP 正在使用你的位置
                [_locationM requestWhenInUseAuthorization];
                
                // 前后台定位
                // 无论是否勾选后台模式, 都可以获取位置信息. 而且无论前后台, 都不会出现蓝条
                // [_locationM requestAlwaysAuthorization];
                
                // 如果是iOS9.0之后, 当前授权状态是前台定位授权状态, 也想在后台获取用户的位置信息,那么需要满足以下条件
                // 1. 勾选后台模式   2. 设置以下属性为YES(Swift, 里面是true)
                if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
                    _locationM.allowsBackgroundLocationUpdates = YES;
                }
            }
            
            // 4. 设置定位的过滤距离(单位:米), 表示用户位置移动了x米时调用对应的代理方法
            _locationM.distanceFilter = 500; //在用户位置改变500米时调用一次代理方法
            
            // 5. 设置定位的精确度 (单位:米),(定位精确度越高, 越耗电, 定位的速度越慢)
            _locationM.desiredAccuracy = kCLLocationAccuracyBest;
        }
        return _locationM;
    }
    
    
    【Swift语言】
    
        // 懒加载
        lazy var locationM : CLLocationManager = {
            
            // 1. 创建位置管理者
            let locationM : CLLocationManager = CLLocationManager()
            
            // 2. 设置代理, 接收位置数据(其他方式:block、通知)
            locationM.delegate = self
            
            // 3.定位(在info.plist文件中配置对应的key)
            
            // 如果两个授权都请求,那么先执行前面那个请求弹框,后面那个请求授权 有可能 下次被调用时,才会起作用
            // 如果,先请求的是“前后台授权”,那“前台授权”即使被调用,也不会有反应(因为“前后台授权”权限大于“前台授权”)
            // 反之,如果先请求的是“前台授权”,而且用户选中的是“允许”,那下次被调用时“前后台授权”会做出请求,但只请求一次
            
            // 本质:1. 两个授权同时请求,先执行前面那个授权请求
            //      2. “前后台请求授权”方法,在(当前的授权状态 == 用户未选择状态 or 前台授权状态) 才会起作用
            //      3. “前台请求授权”方法,在(当前的授权状态 == 用户未选择状态) 才会起作用
            
            // 判断系统版本,做适配
            if (Float(UIDevice.current.systemVersion)! >= 8.0){
            
                // 前台定位
                // 配合后台模式,屏幕上方会出现一个蓝色的横幅, 不断提醒用户, 当前APP 正在使用你的位置
                locationM.requestWhenInUseAuthorization()
                
                // 前后台定位
                // 无论是否勾选后台模式, 都可以获取位置信息. 而且无论前后台, 都不会出现蓝条
                // locationM.requestAlwaysAuthorization()
                
                // 如果是iOS9.0之后, 当前授权状态是前台定位授权状态, 也想在后台获取用户的位置信息,那么需要满足以下条件
                // 1. 勾选后台模式   2. 设置以下属性为true(OC, 里面是YES)
                if (Float(UIDevice.current.systemVersion)! >= 9.0){
                    locationM.allowsBackgroundLocationUpdates = true
                }
            }
            
            // 4. 设置过滤距离
            // 如果当前位置, 距离上一次的位置之间的物理距离大于以下数值时, 就会通过代理, 将当前位置告诉外界
            locationM.distanceFilter = 100   // 每隔100 米定位一次
            
            // 5. 设置定位的精确度(定位精确度越高, 越耗电, 定位的速度越慢)
            locationM.desiredAccuracy = kCLLocationAccuracyBest
            
            return locationM
        }()
    
    

    【区别】前台定位 &前后台定位



    本文源码 Demo 详见 Github
    https://github.com/shorfng/iOS_7.0_Device-Tools


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

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

    【代码托管平台】

    Github

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

    评论区回复
    发送邮件shorfng@126.com


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


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


    • 你也可以微信 向我打赏


    相关文章

      网友评论

        本文标题:【iOS】7.4 定位服务->2.1.3.1 定位 - 官

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