当肾Phone出现,定位服务一直都是做为一个前沿技术跟中心存在。CL API在肾平台SDK第一次发布的时候就列入了公开接口。在每次新发布的iOS版本中,大苹果老是按部就班的增长一些新功能到CL框架,好比后台定位,geocoding亦或是iBeacons。数组
iOS8义无反顾往前走。更其余领域的最新更新同样,CL已经动摇了,随着新设计容许让开发去建立以前他们没法完成的新东西的同时还帮助保护用户隐私。特别的,iOS8为CL框架带了3套主要的改变:更粗糙的受权,室内定位,还有访问监控。网络
APP有多种缘由像你获取地址信息受权。(此处省略各类缘由举栗子)app
iOS8之前,定位服务受权是二进制的:给或者不给。设置的应用选项会展现那些是你受权后台定位服务的APP,可是你除了彻底受权使用定位服务外不能再作其余处理了(短暂使用)。框架
iOS8对这方面作了修正,有如下两种受权方式。异步
这毫无疑问对用户隐私来讲是一个利好,可是对于开发来讲呵呵。。工具
在早先的iOS,定位服务的受权请求是很隐式的。建立一个CLLocationManager
实例,若是用户尚未显示的赞成或者拒绝一个APP的定位服务受权下面得代码会在触发探测用户受权定位服务。this
import Foundation import CoreLocation let manager = CLLocationManager() if CLLocationManager.locationServicesEnabled() { manager.startUpdatingLocation() }
为了让事情简单点,假设上述代码中咱们已经声明了
manager
实例做为成员变量,而且也设置了它的代理。url
每次让CLLocationManager
获取最新地址信息的动做都会弹出定位服务受权框。spa
在iOS8,请求受权与开始使用定位服务是两个不一样的动做。特别地,这里有两个不一样的方法你能够用来显式的请求受权requestWhenInUseAuthorization
和requestAlwaysAuthorization
。前者只是容许你在应用打开得时候获取地位位置信息。后者则容许一直在后台获取地理位置信息。操作系统
if CLLocationManager.authorizationStatus() == .NotDetermined { manager.requestWhenInUseAuthorization() }
或
if CLLocationManager.authorizationStatus() == .NotDetermined { manager.requestAlwaysAuthorization() }
由于受权动做是异步的,因此应用不能立刻开始使用定位服务。相反,应用中必须实现locationManager:didChangeAuthorizationStatus
的代理方法,这个代理方法当用户改变当前的受权权限的时候将会被发送。
若是用户上一次授予用户定位服务的权限,这个代理方法将会在定位管理者被初始化以后而且它的代理被设置成正确的受权状态后被调用。这样将便于代码进行定位服务。
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) { if status == .AuthorizedAlways || status == .AuthorizedWhenInUse { manager.startUpdatingLocation() // ... } }
另一个变化是iOS8中要求使用定位服务。在过去,info.plist
中选择性包含一个NSLocationUsageDescription
的Key.这个值是在向用户申请定位服务的时候展现给用户看的一段字符串。如今被分割为了两个Keys(NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription
),而且如今更增强制了;若是你调用了requestWhenInUseAuthorization or requestAlwaysAuthorization
而没有使用相对应得Key,那么这段提示不会展现给用户。
另一个值得注意的地方是受权弹出将只给用户展现一次。若CLLocationManager.authorizationStatus()
返回值不为NotDetermined
,此时调用requestWhenInUseAuthorization() or requestAlwaysAuthorization()
将不会给用户展现告警栏。在用户最初选择以后,惟一改变受权设置的方式是到设置里的用户隐私条款设置里面进行对应APP相关设置。
尽管在旧操做系统上有诸多不便,在一个应用的生命周期内最显著麻烦的事情主要是“使用权限”跟“永久权限”的请求。大苹果为了缓和这个情况,提出了字符串常量,UIApplicationOpenSettingsURLString
,提供了一个URL用来打开机器的设置界面。
这里是一个实例代码教你让APP打开设置界面获取永久权限:
switch CLLocationManager.authorizationStatus() { case .Authorized: // ... case .NotDetermined: manager.requestWhenAlwaysAuthorization() case .AuthorizedWhenInUse, .Restricted, .Denied: let alertController = UIAlertController( title: "Background Location Access Disabled", message: "In order to be notified about adorable kittens near you, please open this app's settings and set location access to 'Always'.", preferredStyle: .Alert) let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil) alertController.addAction(cancelAction) let openAction = UIAlertAction(title: "Open Settings", style: .Default) { (action) in if let url = NSURL(string:UIApplicationOpenSettingsURLString) { UIApplication.sharedApplication().openURL(url) } } alertController.addAction(openAction) self.presentViewController(alertController, animated: true, completion: nil) }
全部新的API都已iOS8做为根本。对于仍然须要支持iOS7或更早版本,咱们必须维护两个平行代码-一个是iOS8显示的索取权限和另一个仅仅是要求获取地理位置信息更新。一个简单得实现以下:
func triggerLocationServices() { if CLLocationManager.locationServicesEnabled() { if self.manager.respondsToSelector("requestWhenInUseAuthorization") { manager.requestWhenInUseAuthorization() } else { startUpdatingLocation() } } } func startUpdatingLocation() { manager.startUpdatingLocation() } // MARK: - CLLocationManagerDelegate func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) { if status == .AuthorizedWhenInUse || status == .Authorized { startUpdatingLocation() } }
在iOS8全部得改变上跑着共同的一条线索:那就是它们(改变)容易地获取用户的信任。
显式请求受权鼓励应用不要等到用户准备作某些事情须要受权的时候才去请求用户受权。(略)
大苹果尊重用户的我的选择。。。(略)
当你细读CL框架的时候可能会对CLFloor对象产生疑惑,这个新对象有以下简单得接口:
class CLFloor : NSObject { var level: Int { get } }
就这么简单,一个简单属性,告诉你你如今在一个建筑的几楼。
欧洲人说底层是0楼不是1楼。。
一个CLLocationManager
返回的CLLocation
对象可能带有一个floor
属性,可是你若写一个使用定位服务的栗子APP你会发现你的CLLocation
对象中的floor
属性为nil
。
这是由于API改变是冰山的尖端以此来为iOS8带来一套新特征从而便利室内定位跟踪(我晕菜了)。对于开发者为大空间建筑物设计应用的时候,好比博物馆或者大型商场,大苹果提供了支持IPS的工具经过使用内置CL APIs和WiFi,GPS,蜂窝式网络,还有iBeacon数据混用的方式。
大概说了这个技术现状是商用上严格控制。。。
在不少应用,使用位置定位来判断用户是否是在某个指望的地理位置。概念上说,你会将这个行为想成名词“现场”或者是“访问”而不是原生的GPS定位。
略一段。。
在iOS8中,大苹果为咱们解决此类问题提供了CLVisit
,一个新的后台定位监测类型。一个但一个的CLVisit
表示用户花了一段时间在一个单一的地方,包含了同一地理坐标以及起始/结束时间戳。
理论上来讲,使用访问监控不会比其余的后台定位作更多的活儿。简单得调用manager.startMonitoringVisits()
能够启动后台访问定位,假设用户已经永久受权。一旦启动,你的APP将会被后台激活当有新的更新到来的时候(让我想到了乐动力这个APP)。与基础的定位不一样,若是系统有一些的访问更新队列,你的代理方法locationManager:didReceiveUpdates:
将会调用屡次,每次都只调用一个访问,而不是一个CLLocation
对象数组。调用manager.stopMonitoringVisits()
将会中止定位跟踪。
每一个CLVisit
对象包含着一些基础属性:平均坐标,水平精度,以及数据到达与离开得时间戳。
每次访问被记录,CLLocationManagerDelegate
会被通知两次:一旦用户刚到达一个新地点,一个用户刚准备离开这个地点。你能够经过departureDate
属性计算出它们哪一个是哪一个;若是离开时间是NSDate.distantFuture()
意味着用户还在那儿。
func locationManager(manager: CLLocationManager!, didVisit visit: CLVisit!) { if visit.departureDate.isEqualToDate(NSDate.distantFuture()) { // User has arrived, but not left, the location } else { // The visit is complete } }
略。。。。