标签:objective-c 框架
在你的应用中使用基于位置信息的服务可以很好的使用户保持于周围世界的连接.当你为了特殊的目的(比如导航)或者娱乐,使用基于位置信息的服务可以整体增强用户的体验.
基于位置信息服务包含两个方面: 定位服务和地图. 定位服务通过 Core Location framework
来提供,它定义了一些Objective-C的接口来获取用户的location(位置)和heading(设备指向的方向). 地图是通过Map Kit framework
来提供,它支持显示和标注,就像iOS应用中自带的地图应用一样.(为了使用地图服务,你必须打开Xcode工程中得地图能力, Target->Capabilities)
通过将地理数据放置在应用中,你可以将用户放在周围的环境中,并连接周围的人.
因为地图和定位服务在iOS和OS X 都可用,基于定位的应用的代码在两个平台上是差不多的. 不同的是UI相关的代码(比如 在iOS中使用UIView,而在OS X 中使用 NSView) 和一些功能的支持(比如方向服务只在iOS中有).
知道用户的地理位置可以提高用户的体验,甚至是应用的核心功能.有导航功能的应用使用位置服务去监听用户的位置变化和更新,其他使用位置服务的应用可以提供周围用户社交功能.
iBeacon发射机提供一种方法来创建和监测信号,使用蓝牙低能耗无线技术宣传某些识别信息. 在应用中使用 Core Location监听在低能耗蓝牙信号塔信号范围内UUID相同的信号. 当一个信号在用户设备范围内,应用还可以监听与信号的距离.
你可以使用这些信号来发送广告来增强用户在特殊位置的体验.比如说一个博物馆的应用可以监听周围博物馆重要的展览.当用户处理一个展览的时候,应用可以使用相对距离最为一个线索来提供更多的关于这个展览的信息.
因为信号塔广告使用的时低能耗蓝牙传输,你可以将任何一部iOS支持蓝牙的设备接入信号范围.
Heading服务通过基础的定位服务提供了更多的设备方向的精确信息.
最为显著使用这个服务的应用是陀螺仪,但是你也可以使用在增强现实,游戏和地图导航上.即使设备上没有磁力计–获取heading信息的硬件,
也可以获取应用需要的航线和速度信息.
地图是帮助用户通过可视化的 方式去理解地理数据.例如:地图可以在一个范围内显示卫星数据,或者将地图放在一个有角度和三维数据的3D视图.你可以将地图框架中得标准视图放在你的应用中去展示相关地理位置的信息.另外这个框架允许我们自己在地图上展示相关数据,滚动地图和截取当前位置截屏.
一个线路应用可以从地图应用中获取坐标信息,然后提供给用户点到点的路线. 一个提供导航的应用可以声明自己是一个线路应用,添加了额外的开车或走路的方向,线路应用也支持其他类型的交通,如出租车,飞机和其他公共交通.
用户通过描述信息找到位置,比如一个名字, 地址或商业类型.使用地图框架可以通过用户的输入搜索并显示在地图中.
应用为了多种目标使用位置信息,从社交网络到逐向道路导航服务.应用通过Core Location framework
来获取数据.这个框架提供了几种用户获取用户位置和监听设备位置的方式:
如果你的iOS应用 ,如果你的应用需要在适当的时候使用位置信息,在应用的Info.plist
文件中加入 UIRequiredDeviceCapabilities键. 苹果应用商店使用这个值去阻止那些没有功能的设备下载应用.
UIRequiredDeviceCapabilities 的值是一个包含相关功能字符串的数组. 两个字符串与定位服务有关:
- location-services
,通常的定位服务
- gps
, 只通过硬件提供精准的位置
重要:如果你的应用使用了定位服务,但是可以正常的在没有定位服务的情况下完成操作,就不要包含UIRequiredDeviceCapabilities键值
Core Location framework可以让我们获取用户设备的当前位置信息并用于我们的应用中.框架报告位置信息取决于你的代码是如何配置这个服务的,并且当收到新的数据提供周期性的更新.
两个服务可以给我们当前用户位置信息:
Info,plist
文件中设置UIBackgroundModes
的值为location
,这样可以在后台运行并接受更新.而且要确定 location manager的pausesLocationUpdatesAutomatically
属性设置为YES. 比如需要这种类型的服务是运动类的,导航类的等.这里有一些情况使得位置服务不可用:
- 用户在系统设置里面关闭了位置服务功能
- 用户对某个应用关闭的位置服务功能
- 设备在飞行模式和没有电量启动
基于这些原因, 建议你在开始使用位置服务或者重大变化位置服务之前保持调用类 CLLocationManager
的类方法locationServicesEnabled
来判断位置服务功能是否开启. 如果位置服务没有开启,而开始定位,系统会提示用户是否要开启位置服务,比如用户会主动关闭服务,所以提示会不友好.
标准位置服务是最通用的方式获取用户位置信息的方式,因为他在iOS和OS X都可用.在使用服务之前,你需要配置位置服务的精确度和位置报告需要的移动的距离. 当我们开启服务后,服务会通过特殊参数去决定硬件的打开和报告位置时间给应用.因为服务考虑这些参数,需要应用更细粒度的去控制位置事件的传递.标准定位服务的精确度是被导航应用或其他需要高精度位置的应用需要的.因为这个服务通常需要设备硬件开启位置追踪一段时间,但会导致高电量使用.
使用标准位置服务,创建一个CLLocationManager
类的实例,配置它的desiredAccuracy
和distanceFilter
属性.为了能开始接受位置通知,指定一个代理对象,然后调用 startUpdatingLocation
方法.当位置数据可用的时候,CLLocationManager
会通过代理方法通知给代理着. 如果你一位置更新已经被传递了,我们可以通过CLLocationManager
对象获取当前位置的更多数据,要想停止更新位置,调用stopUpdatingLocation
方法.
创建方法如下:
- (void)startStandardUpdates
{
// Create the location manager if this object does
// already have one.
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
// Set a movement threshold for new events.
locationManager.distanceFilter = 500; // meters
[locationManager startUpdatingLocation];
}
这个服务提供了足以使大多数应用使用的精确度,而且比标准位置服务更省电.这个服务使用Wi-Fi来判断用户的位置和报告位置,使用系统来管理用电,这样会更好.这个服务也可以唤醒被挂起或未运行的应用来传递位置事件.
使用服务, 创建一个CLLocationManager
实例,设置代理者,调用startMonitoringSignificantLocationChanges
方法,同样,如果位置数据已经被传递出来,我们可以通过CLLocationManager
实例对象的属性来获取更多的信息而不用等待新位置事件.
下面是代码示例:
- (void)startSignificantChangeUpdates
{
// Create the location manager if this object does not
// already have one.
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
??????
locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];
}
停止重大变化位置服务需要调用stopMonitoringSignificantLocationChanges
方法
如果我们保持重大变化位置服务持续开启的话,如果我们的应用被挂起或终结,这个服务会在有线的位置信息到达的时候唤醒我们的应用.在被唤醒期间,应用被放置在后台,我们有一点时间(大约10秒)去重启位置服务和处理位置数据.因为应用在后台,只能做一些小工作和避免阻止事件返回. 如果是那样,应用会被终结.如果应用需要更多的时间处理事件, 可以请求后台执行时间,调用UIApplication
类的方法beginBackgroundTaskWithName:expirationHandler
如果用户关闭了后台应用刷新的功能, 重大变化位置服务是不能唤醒应用的.而且,当后台应用刷新的功能关闭后,即使应用在前台也不能收到位置更新的事件了
不论使用标准位置服务还是重大变化位置服务,收到位置数据的方式是一样的.从OS X10.9和iOS6以后,location manager 通过代理方法locationManager:didUpdateLocations
报告位置数据,在以前的版本,使用locationManager:didUpdateToLocation:fromLocation
方法.
如果更新位置失败,会调用locationManager:didFailWithError
代理方法.
下图显示代理方法收到位置数据.因为location manager 有时候会返回缓存的位置事件,推荐我们检查每一个位置事件的时间戳来判断是否为新位置数据(它可能要花上几秒钟的时间获得一个粗略的位置固定,所以旧的数据只是作为一种反映了最后的位置–意思就是系统需要一点事件来获取新数据,返回缓存的数据是为了保持数据报告).在这个例子中,只会处理15秒内的新位置数据.
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
// If it‘s a relatively recent event, turn off updates to save power.
CLLocation* location = [locations lastObject];
NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0) {
// If the event is recent, do something with it.
NSLog(@"latitude %+.6f, longitude%+.6f\n", location.coordinate.latitude,location.coordinate.longitude);
}
}
除了位置信息的时间戳,我们也可以使用数据 的精确度来判断是否使用这次位置事件.当收到更精确的数据,服务会返回更多的事件.丢弃低精度的事件,意味着应用可以减少浪费在不能用的数据上.
应用应该在使用位置服务之前才开始开启服务. 而不要在应用已启动就开启位置服务. 另外,我们应该让用户知道我们为什么使用位置服务.用户知道应用何时开启位置服务, 因为第一次开启服务会提示用户授权.直到展示了使用位置服务功能的一面给用户,与用户建立信任关系.另一个建立信任的方式是在Info.plist
文件中添加NSLocationUsageDescription
键, 值为描述为何使用位置服务.
如果我们追踪地区或者使用重大变化位置服务,有一些情况我们必须在应用启动的时候开启服务. 使用这些服务的应用可以被终结然后当新位置事件到达后唤醒应用. 然而,应用自己重启的, 位置服务是不会自动重启的. 当应用重启是被位置服务重启的, 会在应用代理方法 application:willFinishLaunchingWithOptions:
或 application:didFinishLaunchingWithOptions:
的参数中会带有UIApplicationLaunchOptionsLocationKey
键值对.这里面的值是新位置信息的数据.为了获取这些数据,我们必须创建一个新的CLLocationManager
对象,重启位置服务,随后被挂起的更新会通过代理方法传递.
iOS支持应用在挂起或未运行的时候传递位置事件.位置事件在后台传递给那些没有损害用户的应用,所以配置我们的应用去接受位置事件来提供给用户有形的好处.例如全程导航应用需要一直追踪用户位置信息然后可以在下一个转弯处通知用户.
我们可以有许多选择去获取后台位置服务,每种服务都有好处和坏处,因为取决于电力消耗和定位精确度. 如果可以, 应用可以使用重大变化位置服务,它会使用Wi-Fi来决定用户的位置并且可以节约电量.但是你的应用需要好精度的位置数据,我们可以配置应用为后台应用并使用标准定位服务.
如果iOS应用需要持续的位置更新服务,可以在后台使用标准位置服务. 开启后台服务需要在Xcode项目Capabilities中开启Background Modes,设置开启Location updates mode. 我们写得标准位置服务的代码不需要改变.
系统会传递位置事件给应用,不论应用是在前台,后台还是挂起.如果应用挂起, 系统会唤醒应用,传递位置事件给应用,然后立即再次挂起应用.如果应用在后台运行, 应用有一点时间去处理位置事件.
当位置服务开启,设备必须开启才能获取新位置数据.保持位置服务运行会降低电池寿命,我们应该在不使用位置数据的时候关闭位置服务.
如果我们必须在后台使用位置服务,我们可以帮助 Core Location来为用户设备保持电池的寿命,通过以下几步来设置 location manager 对象:
pausesLocationUpdatesAutomatically
属性设置为YES.当设置为YES的时候,Core Location会在合适的时候停止服务,比如用户没有移动activityType
属性设置适当的值.这个值可以帮助location manager 知道何时是可以安全的停止服务的.一个提供全程手机导航的应用设置了值为CLActivityTypeAutomotiveNavigation
,会导致location manager在用户没有在一段时间内移动很大距离的时候关闭服务.allowDeferredLocationUpdatesUntilTraveled:timeout
去延迟一段时间或距离来传递位置事件.当location manager 暂停了服务,它会通知代理方法locationManagerDidPauseLocationUpdates
.当location manager恢复服务,会通知代理方法locationManagerDidResumeLocationUpdates
.我们可以使用这些方法来适应应用功能.比如,当位置服务暂停了,我们可能需要保存数据等.一个导航应用可能需要提示用户导航暂停等.
提示: 如果应用被系统或用户终结掉,系统不会在新位置事件到达的时候重启我们的应用.在位置服务恢复之前用户必须手动重启我们的应用. 让我们的应用自动重启的唯一方式是使用地区监视或重大变化位置服务.
但是用户为某个应用关闭或关闭全部后台刷新功能,系统不会重启应用,即使使用了地区监视或重大变化位置服务. 当后台刷新功能关闭后,地区监视或重大变化位置服务不会发送位置事件,即使应用在前台.但是当用户重新开启后台刷新服务后,Core Location会重新保存后台服务,包括之前注册的地区
在iOS6以后,我们在后台可以推迟位置事件更新.当应用使用推迟的位置数据没有问题的时候,推荐我们使用这个功能.比如一个健康应用 监视用户徒步数据,可以在用户行走了一段距离后或时间后更新一次.推迟更新可以节约设备电量.因为推迟更新服务需要GPS硬件的支持,确保在使用之前调用类CLLocationManager
的类方法deferredLocationUpdatesAvailable
来判断是否支持.
调用类CLLocationManager
的方法allowDeferredLocationUpdatesUntilTraveled:timeout
开始推迟位置更新服务.重复调用allowDeferredLocationUpdatesUntilTraveled:timeout
来设置推迟位置更新服务.
实例代码:
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
// Add the new locations to the hike
[self.hike addLocations:locations];
// Defer updates until the user hikes a certain distance
// or when a certain amount of time has passed.
if (!self.deferringUpdates) {
CLLocationDistance distance = self.hike.goal - self.hike.distance;
NSTimeInterval time = [self.nextAudible timeIntervalSinceNow];
[locationManager allowDeferredLocationUpdatesUntilTraveled:distance
timeout:time];
self.deferringUpdates = YES;
} }
当达到了allowDeferredLocationUpdatesUntilTraveled:timeout
的设置条件,location manager会调用locationManager:didFinishDeferredUpdatesWithError
方法通知代理者.只要调用一次allowDeferredLocationUpdatesUntilTraveled:timeout
开始方法, 就是被通知一次结束方法locationManager:didFinishDeferredUpdatesWithError
.当位置事件传递完会调用locationManager:didUpdateLocations
. 我们可以停止推迟位置服务,调用CLLocationManager
的类方法stopUpdatingLocation
, 然后 代理方法locationManager:didFinishDeferredUpdatesWithError
会调用,表示服务停止.
在iOS设备上获取位置信息需要很多电量.因为大多数应用不需要一直运行位置服务.当不需要位置服务的时候关闭它是最简单的办法:
- 当应用不需要位置服务的时候关闭它们.
- 尽可能的使用重大变化位置服务代替标准位置服务
- 在不损害应用的情况下使用低精度的值获取位置事件
- 如果在一段时间内精确度不在增长,关闭服务
- 在标准位置服务中使用合适的activity type
- 允许location manager推迟传递位置事件
Location and Maps Programing Guide(一)
标签:objective-c 框架
原文地址:http://blog.csdn.net/mysevenmi/article/details/47075751