We're sunsetting PodQuest on 2025-07-28. Thank you for your support!
Export Podcast Subscriptions
cover of episode 390. nshipster-Core Location in i​OS 8

390. nshipster-Core Location in i​OS 8

2016/3/9
logo of podcast iOSDevLog

iOSDevLog

Shownotes Transcript

http://nshipster.cn/core-location-in-ios-8/Core Location in i​OS 8Mike Lazer-Walker撰写、 April Peng翻译、 发布于2014年11月10日自从 iPhone 存在以来,位置服务就一直处于非常重要的位置。Maps.app 是第一代 iPhone 里杀手锏的功能之一。Core Location API 也在 iPhone OS SDK 最初的公开版本里就存在了。每一次发布 iOS,Apple 都会给这个库逐步添加新功能,比如后台运行的位置服务,坐标化,以及室内定位( iBeacons )。iOS 8 仍然继续坚定的延续着这个进程。跟其他最新的更新类似,Core Location 被改动了不少,不管是允许开发者做之前并不被允许的开发,还是帮助维护用户隐私。更特别的是,iOS 8 给 Core Location 带来了三个主要的改进:更分化的权限,室内定位以及访问监控。权限一个 app 总有各种各样的理由需要得到你的位置信息。一个能够提示你每个转弯在哪里的 GPS 应用就需要持续获得你的位置信息,才可以在转弯的时候提示你。一个餐厅推荐的 app 也需要得到你的位置信息(即便它并没有打开的情况下),才可以在你到你朋友点赞的餐厅附近的时候能收到推送消息。一个 Twitter 应用在发推的时候也可能需要你的位置,但在你不使用的时候不应该监控你的位置。在 iOS 8 之前,位置服务的权限是二元的:你要么赋予一个应用得到使用位置服务的权限,要么不给。你可以在 Settings.app 查看哪些 app 可以在后台取得你的位置信息,但除了完全不让这个 app 使用位置服务之外,你不能做任何的事来阻止它获取位置信息。iOS 8 修改了这个问题,它把位置服务权限拆分成了 2 个不同的授权。“使用期间” 的授权会只允许应用在 - 就跟你猜测的一样 - 使用期间取得你的位置信息。“始终” 的授权则跟之前版本的 iOS 那样,会给应用后台权限。这是对用户隐私的一个重大改进,但对于我们开发者来说则意味着多一些的工作。取得权限在早前的 iOS 版本中,获取位置服务权限是隐式的。比如 CLLocationManager,如果应用程序还没有被许可或者之前被拒绝了的话,下面的代码会触发系统弹出提示框向用户获取位置服务的授权:Swiftimport Foundationimport CoreLocationlet manager = CLLocationManager()if CLLocationManager.locationServicesEnabled() { manager.startUpdatingLocation()}把事情简化一下,假定我们声明了一个 manager 实例作为所有例子的成员变量,它的 delegate 是它的 owner。让 CLLocationManager 取得最新的位置的这个操作会让系统弹出是否允许位置服务的提示。在 iOS 8,取得权限和使用位置服务已经分成两个动作了。分别用两个不同的方法取得权限:requestWhenInUseAuthorization 和 requestAlwaysAuthorization。前者只能让应用在使用的时候有权获取位置数据;后者会得到跟之前 iOS 一样的后台位置服务。Swiftif CLLocationManager.authorizationStatus() == .NotDetermined { manager.requestAlwaysAuthorization()}或者Swiftif CLLocationManager.authorizationStatus() == .NotDetermined { manager.requestWhenInUseAuthorization()}因为这是异步的,应用不能立即开始使用位置服务。取而代之的是,应用必须实现 locationManager:didChangeAuthorizationStatus 的 delegate 方法,这个方法会在用户改变权限状态的时候调用。如果用户之前已经授权了位置服务,那么在每次位置管理器被初始化,并且 delegate 被设置了相应的权限状态的情况下这个代理方法仍然会被调用。这使得一个单一的代码路径使用定位服务更为方便。Swiftfunc locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus){ if status == .AuthorizedAlways || status == .AuthorizedWhenInUse { manager.startUpdatingLocation() // ... }}描述字符串