《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

本节书摘来自异步社区《iOS组件与框架——iOS SDK高级特性剖析》一书中的第2章,第2.2节获取用户的位置,作者 【美】Kyle Richter , Joe Keeley,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.2 获取用户的位置
iOS组件与框架——iOS SDK高级特性剖析
要使用 Core Location 获取设备的当前位置,需要执行多个步骤。只有在得到用户许可的情况下,应用才能获取设备的当前位置;获取设备位置前,应用还必须确保设备启用了定位服务。满足这些条件后,应用便可启动位置请求,并对Core Location提供的结果进行分析和使用。本节将详细介绍这些步骤。

2.2.1 需求和许可
要在应用中使用Core Location,需要将框架CoreLocation加入项目目标,并根据需要导入CoreLocation头文件:


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

Core Location尊重用户隐私,仅在用户许可时获取设备的当前位置。在应用“设置”的“隐私”部分,可在设备上关闭或开启定位服务,还可禁止或允许特定应用获取位置信息,如图2.1所示。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

要请求用户允许使用定位服务,应用需要让CLLocationManager开始更新当前位置或将MKMapView实例的属性ShowsUserLocation设置为YES。如果设备关闭了定位服务,Core Location 将提醒用户在应用“设置”中开启定位服务,让应用能够获取当前位置,如图 2.2所示。

如果位置管理器以前未请求用户允许获取设备的位置,它将显示一个提醒框,请求用户许可,如图2.3所示。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

图2.3 示例应用FavoritePlaces使用提醒框请求用户允许获取设备的位置

如果用户轻按OK按钮,说明得到了用户的许可,位置管理器将获取当前位置。如果用户轻按按钮Don’t Allow禁止获取当前位置,将调用CLLocationManager的委托ICFLocationManager中响应授权状态变化的方法。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

在这个示例应用中,ICFLocationManager存储其他地方的位置请求结束块,以便能够轻松地处理多个位置请求。位置可用或发生错误时,方法getLocationWithCompletionBlock:将执行存储的所有结束块,让调用者能够根据当前的情况以合适的方式使用位置或处理错误。用户禁止获取当前位置时,调用者显示一个提醒框,指出发生了位置获取请求遭拒错误,如图2.4所示。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

在示例应用中,这个方法是在ICFLocationManager中实现的,它在未获得用户许可时显示错误提示,在得到用户许可时重启位置更新并清除以前的错误。

2.2.2 检查定位服务是否已开启
要直接检查设备是否开启了定位服务,可使用CLLocationManager的类方法location ServicesEnabled。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

使用这个类方法,可让应用根据能否获取当前位置采取不同的措施。在使用位置的应用中,应在用户禁止获取当前位置时采取妥善的措施,并清楚地告诉用户,如果他想让应用获取当前位置,该如何做。

2.2.3 开始位置请求
获得使用定位服务的许可后,便可使用CLLocationManager实例来获取当前位置了。在示例应用中,ICFLocationManager负责集中管理位置功能,它为应用管理着一个CLLocationManager实例。在ICFLocationManager类的方法init中,创建了一个CLLocationManager实例,并根据定位需求对其进行了定制。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

可设置CLLocationManager的多个属性,以指定它如何管理当前位置。通过设置精度属性desiredAccuracy,应用可告诉CLLocationManager,该以缩短电池续航时间为代价尽可能提高精度,还是为延长电池续航时间而使用较低的精度。使用较低的精度时,还可缩短获取当前位置所需的时间。通过设置属性distanceFilter,可告诉CLLocationManager,移动多长距离后才触发新的位置事件;这对微调基于位置变化的功能很有帮助。最后,给CLLocationManager指定了委托,这使得可以独特的方式响应位置事件和授权状态变化。为获取位置做好准备后,让位置管理器开始更新位置。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

CLLocationManager将根据指定的参数在需要时利用GPS和/或Wi-Fi确定当前位置。应实现两个委托方法,它们分别处理如下情形:位置管理器更新了当前位置或无法更新当前位置。获取位置后,将调用方法locationManager:didUpdateLocations:。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

位置管理器可能通过数组locations提供多个位置,其中最后一个对象是最新的位置。位置管理器还可能在没有开始获取位置时,就快速返回GPS检测到的最后位置;在这种情况下,如果GPS已关闭且设备发生了移动,返回的位置将很不准确。这个方法检查位置的精度,如果精度值为负,就忽略返回的位置。如果返回的位置相当准确,这个方法就存储它并执行结束块。请注意,在逐步获取准确位置期间,位置管理器可能调用这个方法多次,编写这个方法时必须考虑到这一点。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

如果位置管理器未能获取位置,它将调用方法locationManager:didFailWithError:。导致错误的原因可能是未得到用户的许可,也可能是由于GPS或Wi-Fi不可用(例如,设备处于飞行模式)。发生错误时,示例应用命令位置管理器停止更新当前位置、捕获错误并执行结束块(让请求当前位置的代码能够妥善地处理错误)。

位置管理器委托可监视航向变化,这很有用。例如,可使用这些信息在地图上标出用户的前进路线相对于正确路线的偏差。要获取航向信息,需要让位置管理器对其进行监视。还可设置一个可选的筛选器,这样航向变化小于指定的度数时就不会获取更新。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

参数newHeading提供了多项重要信息,其中包括相对于磁北的航向和相对于真北的航向,它们的单位都是度。它还提供了精度,这指出了磁北航向可能偏离多少度。这个值为越少的正数,航向就越准确;如果为负数,就说明航向无效,这可能是因为存在磁场干扰。时间戳指出了航向是什么时候获取的,应通过检查它来避免使用过时的航向。

2.2.4 分析和理解位置数据
位置管理器返回的位置是用CLLocation实例表示的。CLLocation包含多项有关位置的重要信息,首先是用CLLocationCoordinate2D表示的经度和维度。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

维度指的是位于赤道以北或以南多少度,其中赤道为0度,北极为90度,而南极为-90度。经度指的是位于本初子午线以东或以西多少度;本初子午线是一条虚构的线条,它从北极出发,经英国格林尼治天文台到达南极。位于本初子午线以西时,经度为负数,最高可达-180度;而位于本初子午线以东时,经度为正数,最高可达180度。

作为经度和维度坐标的补充,还有水平精度,它用CLLocationDistance或米数表示。水平精度指的是实际位置与返回的坐标之间的距离在指定米数内。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

2.2.5 重大变化通知
Apple强烈建议应用在获取位置后停止位置更新,以延长电池的续航时间。如果应用不要求位置非常准确,可监视重大位置变化,这是一种高效的方式,既让应用获悉设备的位置发生了重大变化,又可避免让GPS和Wi-Fi不断监视当前位置,从而极大地节省电量。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

通常,在设备位置变化超过500米或更换了连接的基站时,将发出通知。另外,仅当最后一次通知是在 5 分钟之前时,才会发送新的通知。位置更新时间被交给委托方法 locationManager: didUpdateLocations:进行处理。

2.2.6 使用GPX文件进行位置测试
测试基于位置的应用令人望而却步,需要对不方便的位置进行测试时尤其如此。所幸Xcode使用GPX文件提供了强大的位置测试支持。GPX文件是GPS交换格式(Exchange Format)文档,它使用XML格式,可用于在设备和GPS之间交换信息。在调试模式下,Xcode可使用GPX文件定义的“航点”来设置iOS模拟器或设备的当前位置。

在示例应用中,使用文件DMNS.gpx将当前位置设置为丹佛自然科学博物馆(Denver Museum of Nature and Science)。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

要让Xcode使用GPX文件进行调试,可从项目窗口左上角的下拉列表Scheme中选择Edit Scheme,再选择标签Options,并选中复选框Allow Location Simulation,如图2.5所示。选择复选框Allow Location Simulation,便可从下拉列表 Default Location中选择一个位置。这个下拉列表包含一些内置位置,还包含添加到项目中的GPX文件指定的位置。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置

应用在调试模式下运行时,Core Location将返回GPX文件指定的位置,将其作为设备或模拟器的当前位置。要在调试期间改变模拟位置,可从Xcode菜单中选择Debug>Simulate Location,再选择一个位置,如图 2.6 所示。Core Location将把模拟位置改为选定的位置,导致委托方法locationManager:didUpdateLocations:被调用。


《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.2节获取用户的位置
上一篇:初识二叉树,领悟树的概念 | 带你学《Java语言高级特性》之三十八


下一篇:linux的centos版本修改时间重启后无效的问题