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


本文相关目录:

================== 所属文集:【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. svn git协同管理

    项目开发过程中总有一些奇奇怪怪的需求出现. 我们的项目管理是使用SVN的,用SVN是历史原因,无法整个项目向Git切换.由于我需要管理SVN,做一些代码合并工作.每次合并都会遇到SVN代码需要对比查看 ...

  2. iOS initWithFrame、initWithCoder、awakeFromNib的区别解析

    当我们需要自定义一个View控件时,会有 initWithFrame.initWithCoder.awakeFromNib 这三个系统方法,关于这三个方法何时调用,如何调用,有时候可能很多人会弄混淆. ...

  3. Memcached在windows下的安装和使用

    1.下载memcached安装文件及c#开发所需的dll 2.解压<memcached-1.2.6-win32-bin.zip>,并cmd,定位到解压目录. 3.安装服务:输入命令 mem ...

  4. JavaScript Window.document对象

    一.找到元素: docunment.getElementById("id"):根据id找,最多找一个:    var a =docunment.getElementById(&qu ...

  5. js详解之作用域-实例

    函数如下大家可以做做看 function aa(a,b,c){ function a(){} console.log(a); console.log(aa); console.log(argument ...

  6. 关于a.b和a[b]的区别

    在写代码的过程中,我们经常可以看到a.b或啊a[b],但是他们有什么区别呢: 简单说一下吧,有自己的还用群友的大力支持! 在js的对象中 var arr = {a:"b",b:&q ...

  7. 【thinkphp 5 在nginx 环境下路由无法生效(404 500错误 )的解决方法】

      非常惭愧的说,由于之前一直使用的是windowservice,安装apache来进行服务器布置的,这种方式也是最简单最直接的方式, 但是由于php的服务大多都是linux栈的,咱们也不能落后呀,在 ...

  8. WebServerice的发布

    在webserverice一文中,我们简单的介绍了一下什么是webserverice,以及如何建立一个webserverice服务.今天,我们一起学习下webserverice是如何发布的. 为什么要 ...

  9. 《解决在Word中为汉子插入拼音及音标的问题》

    说明:本人使用的是Word2007版本.以下示例都是基于本人电脑操作.如有疑问,欢迎留言交流. [1]为word中的一些文字添加拼音及音标. [2]开始为文字添加拼音及音标. 选中要添加拼音及音标的文 ...

  10. iOS Foundation框架 -1.常用结构体的用法和输出

    1.安装Xcode工具后会自带开发中常用的框架,存放的地址路径是: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.plat ...