本文介绍iOS定位的三种情况:本文介绍iOS定位的三种情况:
  1. iOS前台定位以及不同版本(iOS 7、8、9)之间定位的基本使用和异同点
  2. iOS后台(Background)的持续定位
  3. APP未运行(Not running)被用户or系统强行退出后,系统依然可以自动启动应用,进行关键位置定位startMonitoringSignificantLocationChanges
本文的Demo可以在这里下载查看。

1. iOS前台定位

iOS定位使用步骤

1. 请求授权

从iOS 6 开始,苹果加强了对用户隐私的保护,要使用定位服务,必须先在系统配置文件Info.plist定义Key,用以提醒用户为何使用定位服务,从而提高用户允许定位的概率。添加了key和对应的string后,当应用需要使用定位的时候,会弹出警告框,警告框下面详细的内容就是我们key对应的string。具体的Key参照 CocoaKeys如下:
iOS 6 - 8
Key 为 NSLocationUsageDescription,无论Info.plist中是否有添加NSLocationUsageDescription,系统都会自动弹出警告框,让用户选择是否可以使用定位。
具体在Info.plist添加如下内容:
<key>NSLocationUsageDescription</key>
        <string>这里使用定位服务的原因,提醒用户,提高用户允许定位概率</string>

iOS 8之后
苹果修改了Key,NSLocationUsageDescription被废弃,改用NSLocationWhenInUseUsageDescription和NSLocationAlwaysUsageDescription。
特别注意的是:改动之后,系统不会自动弹出使用定位服务警告框,必须在Info.plist中添加Key才会弹出。
根据自己的需求,选用不同的key,在Info.plist添加如下内容:
<key>NSLocationAlwaysUsageDescription</key>
           <string>这里使用定位服务的原因,提醒用户,提高用户允许定位概率</string>

或者
<key>NSLocationAlwaysUsageDescription</key>
           <string>这里使用定位服务的原因,提醒用户,提高用户允许定位概率</string>

这两个key的异同点:
相同点:都支持后台定位
不同点:
  • 虽然两者都支持后台定位,但是当程序进入后台,进行后台定位时候,使用NSLocationWhenInUseUsageDescription会导致手机上面会有个蓝色状态栏,而NSLocationAlwaysUsageDescription不会有这样的提示。详细信息请看本文第二部分的iOS后台定位。
  • NSLocationAlwaysUsageDescription 支持区域监控(monitor regions)和关键位置改变定位服务(significant location change service),而NSLocationWhenInUseUsageDescription不支持。
  • 因为NSLocationWhenInUseUsageDescription不支持关键位置定位服务,所以当应用被强制关闭后,系统不会再自动唤醒程序进行定位。具体请查看看本文第三部分的iOS应用未启动时进行定位。
特别注意:
今年(2016年)4月份左右,苹果更新了审核规则,如果需要使用后台定位,即使用key值为NSLocationAlwaysUsageDescription,那么必须详细说明为何使用后台定位,也就是说NSLocationAlwaysUsageDescription的描述不能为空,本人就是因为未填写具体使用后台定位原因而导致应用被拒。另外NSLocationAlwaysUsageDescription主要用于后台定位、关键位置定位以及区域监控等。苹果对此审核比较严格,如果应用没有足够的理由使用后台定位,很可能会被拒绝。
所以,如果应用只需要在使用的时候进行定位,那么key至一定要使用NSLocationWhenInUseUsageDescription,避免应用被拒。

2. 导入头文件

定位服务基于Core Location framework框架,所以必须先导入头文件#import <CoreLocation/CoreLocation.h>。

3. 创建定位管理者

创建位置管理者CLLocationManager,并且添加为AppDelegate的属性(其他类的属性亦可),目的是让位置管理CLLocationManager的对象被强引用,否则会被系统销毁,无法进行定位。
然后设置位置管理对象的基本属性如多远定位一次、定位精度等等。

4. 请求定位

如果系统为iOS 8以上,需要定位服务,根据不同的Info.plist中的key需要调用不同的方法requestWhenInUseAuthorization 或者 requestAlwaysAuthorization。

5. 设置代理,实现代理方法

设置管理对象的代理、遵守的协议以及实现响应的代理方法。

6. 开始定位

[manager startUpdatingLocation]

具体代码

#import "AppDelegate.h"
#import <CoreLocation/CoreLocation.h>
@interface AppDelegate ()<CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *manager;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    CLLocationManager *manager = [[CLLocationManager alloc]init];
    _manager = manager;
    manager.delegate = self;
    [manager setDistanceFilter:kCLLocationAccuracyBest]; //设置定位精度
    //如果是iOS8,需要进行请求定位,并根据Key判断调用哪个方法
    if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
        //下面是伪代码,根据Info.plist里面的Key判断调用哪个方法
        if (Key == NSLocationWhenInUseUsageDescription) {
            [manager requestWhenInUseAuthorization];
        }else if (Key == NSLocationAlwaysUsageDescription){
            [manager requestAlwaysAuthorization];
        }
    }
    //如果需要后台定位,key建议为NSLocationAlwaysUsageDescription,如果key值为requestWhenInUseAuthorization,那么当程序进入后台后,系统会在上面显示用户APP正在使用定位
    if (需要后台定位) {
        //iOS9特殊处理
        if ([UIDevice currentDevice].systemVersion.floatValue >= 9.0) {
            [manager setAllowsBackgroundLocationUpdates:YES];
        }
    }
    if ([CLLocationManager locationServicesEnabled]) { //是否开启了定位权限
        [manager startUpdatingLocation];//开始定位
    }
    return YES;
}
-(void)locationManager:(CLLocationManager *)manager
    didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    CLLocation *loc = locations[0];
    NSLog(@"位置更新 -- %@",loc);
    NSString *locSt = [NSString stringWithFormat:@"经度%f  纬度%f 速度 %.1f",loc.coordinate.longitude,loc.coordinate.latitude,loc.speed];
}
@end

2. iOS后台定位

iOS后台定位使用步骤

1. 开启后台定位模式

在info plist文件中对UIBackgroundModes键指定特定的值,可以在 Xcode 的 project editor 中的 Capabilities 标签页中设置,这个标签页包含了后台模式部分,可以方便配置多任务选项。如下图: 
也可以手动编辑这个值
<key>UIBackgroundModes</key>
        <array>
                <string>location</string>
        </array>

2. 执行上面iOS定位的6步

3. 适配iOS 9

如果系统为iOS 9,还必须必须将allowsBackgroundLocationUpdates设置为YES,否则不能进行后台定位。
至此,完成了iOS后台定位的功能。
注意:
key的选择:建议为NSLocationAlwaysUsageDescription,如果key值为NSLocationWhenInUseUsageDescription ,那么当程序进入后台后,系统会在上面显示用户APP正在使用定位,如下图所示: 

3. iOS应用未启动时进行定位

这里介绍应用没有启动(被用户或者系统强制退出)或者应用在休眠状态下,依然可以进行定位。
据我现在的知识,应用被用户或者系统强制退出后,要想让系统后台再自动启动程序,有2种方法:
  1. 使用关键位置定位startMonitoringSignificantLocationChanges
  2. 使用区域检测Region Monitoring
参见:Location and Maps Programming Guide
当然,肯定不止这两种方法,我还会继续研究。当然,如果你知道有什么好的方法,可以在这里告诉我,非常感谢。
iOS关键位置定位使用步骤

1.和iOS后台定位步骤一样

2.取消后台定位模式

特别注意:使用关键位置定位,不需要开始后台定位模式,即不需要执行iOS后台定位中的第一步。也就是说,不需要在info.plist文件中添加:
<key>UIBackgroundModes</key>
        <array>
                <string>location</string>
        </array>
如果开启了后台定位模式,却没有实现相应的后台定位功能,上架的时候很可能会被苹果拒绝。
PS:苹果会根据info.plist的key值判断是否开始了后台定位模式。

3.注意以及需要修改的地方

  1. key一定要选择NSLocationAlwaysUsageDescription。上面介绍过,NSLocationWhenInUseUsageDescription 不支持关键位置定位。
  2. 使用关键位置定位:[manager startMonitoringSignificantLocationChanges],而不是[manager startUpdatingLocation]。

4.回调时间

应用未运行的时候,如果位置发生重大改变,系统会在后台自动启动程序,并进行回调locationManager:didUpdateLocations:,根据苹果文档Location and Maps Programming Guide,回调时间只有10s
In iOS, regions associated with your app are tracked at all times, including when the app isn’t running. If a region boundary is crossed while an app isn’t running, that app is relaunched into the background to handle the event. Similarly, if the app is suspended when the event occurs, it’s woken up and given a short amount of time (around 10 seconds) to handle the event. When necessary, an app can request more background execution time using the beginBackgroundTaskWithExpirationHandler: method of the UIApplication class.
所以,如果我们这时候需要执行耗时操作,比如向服务器上传位置信息,需要调用beginBackgroundTaskWithExpirationHandler 方法,如下:
//如果你需要上传位置信息,且程序处于后台,需要调用beginBackgroundTaskWithExpirationHandler来执行网络请求操作
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
    UIApplication *application = [UIApplication sharedApplication];
    //申请开台时间
    __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //上传地理位置信息..
//            NSURLSession *session = ...
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

具体代码可以在这里下载查看。

5.程序运行效果

程序运行效果如下图: 

4. 其他

这里我们介绍下startUpdatingLocation和startMonitoringSignificantLocationChanges的一些区别

定位方式

定位方式有多种,包括GPS/基站/WIFI/蓝牙等等。
1.startUpdatingLocation定位具体使用哪一种由CoreLocation框架决定。前几天Google了,也查看了苹果的一些文档,得出如下结论:
当我们使用startUpdatingLocation,无法知道设备正在使用哪种方式定位,只能根据定位信息中的定位精度horizontalAccuracy和 verticalAccuracy间接判断使用哪种方式,这种方法得到的结论是正确与否不得而知。
2.startMonitoringSignificantLocationChanges使用的是基站定位,如果设备没有电话模块或者没有SIM卡,该功能无法使用。

定位频率

1.startUpdatingLocation不管位置有没有发生变化,都会进行定位,定位频率比较高。当程序在后台运行的时候,也会因为资源紧张被系统挂起(suspend)或终止(terminate),从而停止定位更新。
2.startMonitoringSignificantLocationChanges根据基站定位,所以,只有设备更换基站的时候调用。 但是苹果文档中Reduce Location Accuracy and Duration这样说:
Significant-change location updates wake the system and your app once every 15 minutes, at minimum, even if no location changes have occurred.
可是经过我测试,发现并不是15分钟启动一次系统,关于这个问题,还有待研究。

iOS 通过定位启动App相关推荐

  1. 微信「扫码支付」被诉侵犯专利权;苹果回应“iOS 13 频繁提醒 App 定位”;Python 2 退休 | 极客头条...

    整理 | 屠敏 快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注 ...

  2. 1月2日科技资讯|微信「扫码支付」被诉侵犯专利权;苹果回应“iOS 13 频繁提醒 App 定位”;Python 2 退休

    CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧.扫描上方二维码进入 CSDN App 可以收听御姐萌妹 Style 的人工版音频哟. 一分钟速览新闻 ...

  3. iOS —— 奇葩问题一 iOS15 首次启动app网络请求失败

    背景: 在iOS15上 首次启动app,如图显示本地网络弹框提示,并且此时所有的网络请求都是失败的. 原因 通过不断测试发现是 手机开通代理导致的, 关闭代理后就不会有如图弹框. iOS15之前的系统 ...

  4. Appium+python自动化19-iOS模拟器(iOS Simulator)安装自家APP

    前言 做过iOS上app测试的小伙伴应该都知道,普通用户安装app都是从appstore下载安装,安装测试版本的app,一般就是开发给的二维码扫码安装, 或者开发给个.ipa的安装包文件,通过itoo ...

  5. iOS性能优化 启动

    为什么80%的码农都做不了架构师?>>>    App启动过程 解析Info.plist 加载相关信息,例如如闪屏 沙箱建立.权限检查 Mach-O加载 如果是胖二进制文件,寻找合适 ...

  6. appium启动app失败_Appium-Desktop Capability 配置及启动App演示

    Appium-Desktop Capability配置介绍 desired capability的功能是配置Appium会话.为什么要配置capability,目的就是为了告诉Appium服务器您想要 ...

  7. python模拟器ipad_Appium+python自动化19-iOS模拟器(iOS Simulator)安装自家APP【转载】

    前言 做过iOS上app测试的小伙伴应该都知道,普通用户安装app都是从appstore下载安装,安装测试版本的app,一般就是开发给的二维码扫码安装, 或者开发给个.ipa的安装包文件,通过itoo ...

  8. iOS应用的启动流程和优化详解

    一.应用启动流程 1.整体过程 (1)解析Info.plist 加载相关信息,例如如闪屏 沙箱建立.权限检查 (2)Mach-O(可执行文件)加载 dylib loading time(动态库耗时) ...

  9. Xcode10打包引起iOS9系统的用户启动App随机崩溃的问题修复记录

    最近更新了Xcode10和macOS10.14,想着可以在暗黑模式下尽情潇洒.然而,在用Xcode10打包提交一个版本之后,线上崩溃接踵而至.这就很尴尬了,发布前,不管是开发自测还是测试同学的调试,都 ...

最新文章

  1. HIVE入门_3_数据导入导出
  2. SAP SD基础知识之创建并处理外向交货单
  3. Java isfile()与exists()的区别
  4. 彻底搞清楚javascript中的require、import和export
  5. centos7离线安装mysql_Centos7离线安装metasploit详细教程
  6. 嵌入式·实时操作系统 xos介绍
  7. Scanner的注意细节
  8. Autograd看这一篇就够了!
  9. Core Data 学习笔记(二)被管理对象模型
  10. 双系统win+ubuntu无法访问win的盘符
  11. 【图像隐写】基于matlab GUI DCT数字水印嵌入+提取【含Matlab源码 1671期】
  12. Dreamweaver cc 2019
  13. 移动硬盘不在计算机显示,移动硬盘在电脑上不显示怎么办
  14. 笔记本无线上网卡的种类
  15. 农夫过河c语言算法,农夫过河
  16. 房租分期业务系统-抓住新的市场机遇
  17. app冷启动与热启动原理,及启动优化
  18. 支付账户跨行转账将被叫停 免费转账时代或终结
  19. 这套动捕方案居然只用一个摄像头?
  20. 准备奔向新时代的技术nodejs+express+mongodb+json

热门文章

  1. 问题解决:CDH6.3.1初始化scm_prepare_database数据库scm为空
  2. Mysqs查询账单-昨天每个用户最后一次交易的金额总和
  3. 毕业设计日志(16)
  4. 重庆北大青鸟解放碑校区J11班 勇往直前队 [OA智能办公系统]
  5. TMS320F28377D.cmd文件分析
  6. 【1 - 决策树 - 案例部分:泰坦尼克号幸存者预测】菜菜sklearn机器学习
  7. 为什么炒股不如炒汇?
  8. springboot整合微信支付宝二合一扫码支付,完整实例代码
  9. introjs,intro.js-react 步骤指引
  10. 剑鱼行动-SSL 1618