iOS 系统自带定位服务

iOS 自带定位服务(原创)

ps:本文粘贴自别处,只为学习记录~

定位服务

iOS 7 提供了4种不同的途径进行定位,具体如下所示。

Wi-Fi。通过 Wi-Fi 路由器的地理位置信息查询,比较省电。iPhone、iPod touch 和 iPad 都可以采用这种方式定位。

蜂窝式移动电话基站。通过移动运用商基站定位。只有 iPhone、3G 版本的 iPod touch和iPad可以采用这种方式定位。

GPS 卫星。通过 GPS 卫星位置定位,这种方式最为准确,但是耗电量大,不能遮挡。iPhone、iPod touch 和 iPad 都可以采用这种方式定位。

iBeacon 微定位。iOS 7支持iBeacon技术,iBeacon 技术是苹果公司研发的,它使用低功耗蓝牙技术,通过多个 iBeacon 基站可以创建一个信号区域(地理围栏),当设备进入该区域时,相应的应用程序便会提示用户进入了这个地理围栏。

在对定位服务编程时,iOS 不像 Android 系统可以指定采用哪种途径进行定位。iOS 的 API 把底层这些细节屏蔽掉了,开发人员和用户并不知道现在设备是采用哪种方式进行定位的(微定位除外),iOS 系统会根据设备的情况 和周围的环境采用一套最佳的解决方案。

也就是说,如果能够接收 GPS 信息,那么设备优先采用 GPS 定位,否则采用Wi-Fi 或蜂窝基站定位。在 Wi-Fi 和蜂窝基站之间,优先使用 Wi-Fi,如果无法连接 Wi-Fi 才使用蜂窝基站定位。

定位服务编程

在 iOS 7 中,定位服务有比较大的变化,主要使用Core Location框架,定位时主要使用 CLLocationManager、 CLLocationManagerDelegate 和 CLLocation 这3个类,下面简要介绍一下它们。

CLLocationManager。用于定位服务管理类,它能够给我们提供位置信息和高度信息,也可以监控设备 进入或离开某个区域,还可以获得设备的运行方向等。

CLLocationManagerDelegate。它是 CLLocationManager 类的委托协议。

CLLocation。该类封装了位置和高度信息。

在定位服务的应用中,第一次请求位置信息时,系统会提示用户是否允许开启定位服务。如图所示,用户所在的位置是比较私 密的信息,应用获取这些信息时,用户是有知情权和否定权的。如果应用在用户不知情的情况下获得其位置信息,这在某些国家是违法的。

iOS 系统自带定位服务_第1张图片

如果用户“不允许”,定位服务就无法获得位置信息了。如果想改变这些设置,可以在系统“设置”应用中 开启或关闭,如图所示。

如图所示,我们可以关闭所有的定位服务,此时只需关闭最上面的“定位服务”开关控件就可以了。 当然,也可以关闭或开启下面的具体应用。

iOS 系统自带定位服务_第2张图片
iOS 系统自带定位服务_第3张图片
iOS 系统自带定位服务_第4张图片

在应用启动进入界面时,会获得位置信息,并显示在对应的文本框中。如果设备位置发生变化,也会重新获取位置信息,并更新对应的文本框。

iOS 系统自带定位服务_第5张图片

首先,为工程引入Core Location框架,具体步骤是选择工程中的TARGETS→WhereAmI→Build Phases→Link Binary With Libraries,选择右下角的+按钮,打开“选择要添加的框架和库”对话框,如图所示。

iOS 系统自带定位服务_第6张图片

ViewController.h 中的代码如下:

iOS 系统自带定位服务_第7张图片

在上述代码中,我们首先引入了CoreLocation/CoreLocation.h和CoreLocation/CLLocationManagerDelegate.h这两个头文件,然后在定义ViewController时声明了CLLocationManagerDelegate协议。此外,我们还定义了CLLocationManager *locationManager属性。 在 ViewController.m 中,viewDidLoad 方法的代码如下:

- (void)viewDidLoad

{

[super viewDidLoad];

//初始化定位服务管理对象

_locationManager = [[CLLocationManager alloc] init];

_locationManager.delegate = self;

_locationManager.desiredAccuracy = kCLLocationAccuracyBest; (1)

_locationManager.distanceFilter = 1000.0f; (2)

}

iOS 系统自带定位服务_第8张图片

在上述代码中,我们主要对CLLocationManager的成员变量_locationManager进行了初始化。首先,使用[[CLLocationManager alloc] init]语句实例化CLLocationManager对象,然后使用_locationManager. delegate = self语句设置定位服务委托为 self。

第(1)行代码设置desiredAccuracy属性,它是一个非常重要 的属性,其取值有6个常量,具体如下所示。

kCLLocationAccuracyNearestTenMeters。精确到10米。

kCLLocationAccuracyHundredMeters。精确到100米。

kCLLocationAccuracyKilometer。精确到1000米。

kCLLocationAccuracyThreeKilometers。精确到3000米。

kCLLocationAccuracyBest。设备使用电池供电时最高的精度。

kCLLocationAccuracyBestForNavigation。导航情况下最高的精度,一般有外接电源时才能使用。

精度越高,请求获得位置信息的时间就越短,这就意味着设备越耗电,因此一个应用应该选择适合它的精度。 如果你的应用是一个车载导航应用,kCLLocationAccuracyBestForNavigation是比较好的选择,你可以使用汽车上的电瓶为设备供电。 如果你的应用是为徒步旅行者提供的导航应用,kCLLocationAccuracyHundredMeters是一个不错的选择。

第(2)行代码设置distanceFilter属性,它是距离过滤器,定义了设备移动后获得位置信息的最小距离,单位是米,本例设置为1000米。 初始化 CLLocationManager 类后,需要使用startUpdatingLocation方法开始定位服务,该方法定义在ViewController.m的viewWillAppear:方法中。viewWillAppear:方法的代码如下:

- (void)viewWillAppear:(BOOL)animated

{

[super viewWillAppear:animated]; //开始定位

[_locationManager startUpdatingLocation];

}

调用startUpdatingLocation方法时,就会开启定位服务。根据设定的条件,它不断请求回调新的位置信息。因此,开启这个方法一定要慎重,在视图控制器的声明周期方法viewWillAppear:中使用这个方法是最合适的。与开启服务对应的方法是stopUpdatingLocation方法,它是在视图控制器的viewWillDisappear:方 法中调用的。viewWillDisappear:方法的代码如下:

- (void)viewWillDisappear:(BOOL)animated

{

[super viewWillDisappear:animated]; //停止定位

[_locationManager stopUpdatingLocation];

}

iOS 系统自带定位服务_第9张图片

这个方法在视图消失(应用退到后台)时调用,能够保证最及时地关闭定位服务。在iOS 6中,请求有所变化, 定位服务应用退入台后,可以延迟更新位置信息,这可以通过allowDeferredLocationUpdatesUntil- Traveled:timeout:方法实现。要关闭延迟更新,可以使用disallowDeferredLocationUpdates方法实现。 此外,在iOS 6中,新增了pausesLocationUpdatesAutomatically属性,它能设定自动暂停位置更新,而把 定位服务的开启和暂停管理权交给系统,这样会更加合理和简单。

一旦定位服务开启,并设置好CLLocationManager委托属性 delegate 后,当用户设备移动到达过滤距离时, 就会回调委托方法。与定位服务有关的方法有如下两个。

locationManager:didUpdateLocations:。定位成功。这是iOS 6中新增的方法,替代了之前的locationManager:didUpdateToLocation:fromLocation:方法。

locationManager:didFailWithError:。定位失败。

实现 CLLocationManager 委托的代码如下:

#pragma mark Core Location委托方法用于实现位置的更新

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:

(NSArray *)locations

{

CLLocation * currLocation = [locations lastObject]; (1)

_txtLat.text = [NSString stringWithFormat:@"%3.5f",currLocation.coordinate.latitude]; (2)

_txtLng.text = [NSString stringWithFormat:@"%3.5f",currLocation.coordinate.longitude]; (3)

_txtAlt.text = [NSString stringWithFormat:@"%3.5f",currLocation.altitude]; (4)

}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

{

NSLog(@"error: %@",error);

}

iOS 系统自带定位服务_第10张图片

在locationManager:didUpdateLocations:方法中,参数locations是位置变化的集合,它按照时间变化的顺序存放。如果想获得当前设备的位置,可以使用 第(1)行中的[locations lastObject]语句获得集合中的最后一个元素,它就是设备的当前位置了。从集合中返回的对象类型是 CLLocation,CLLocation 封装了位置、高度等信息。在上面的代码中,我们使用了它的两个属性altitude和coordinate,其中前者是高度值,后者是封装经度和纬度的结构体CLLocationCoordinate2D。CLLocationCoordinate2D的定义如下:

typedef struct {

CLLocationDegrees latitude; //纬度 CLLocationDegrees longitude; //经度

} CLLocationCoordinate2D;

其中latitude为纬度信息,longitude为经度信息,它们都是CLLocationDegrees类型。CLLocationDegrees是使用typedef定义的double类型。

第(2)行代码中的currLocation.coordinate.latitude表达式用于获得设备当前的纬度,

第(3)行代码中的currLocation.coordinate.longitude表达式用于获得设备当前的经度,

第(4)行代码中的currLocation. altitude表达式用于获得高度。

关于定位服务的测试

一般情况下,定位服务应用的测试和运行有两个选择:模拟器和设备。原则上,我们先通过模拟器,然后再 使用设备测试。由于定位服务的特点,使用设备测试时我们需要到现场进行测试,所以有的时候有一定的局限性。 因此,使用模拟器测试有的时候是不可替代的。

在 Xcode 早期版本中,模拟器是不能模拟位置信息的变化的,请求获取位置信息只是固定苹果公司总部地址。 而现在的 Xcode 版本预先设置了几个地址,我们可以模拟改变位置。如果想让模拟器一开始运行的时候就能够获 得模拟数据,可以在启动参数中设置。首先,在 Xcode 工具的左上角编辑应用的Scheme,如图所示。

iOS 系统自带定位服务_第11张图片

选择Edit Scheme菜单后,弹出如图所示的对话框,从中选择Run WhereAmI.app→Options,在Core Location项目中选中Allow Location Simulation复选框,然后在下面的Default Location下拉框中选择你感兴趣的城市。

iOS 系统自带定位服务_第12张图片

这样应用启动时,就会模拟定位到你选择的城市了。如果列表中没有我们需要的地点,可以使用最下面的Add GPX File to Project菜单项为工程添加一个GPX1文件。下面是 GPX 文件的内容:


creator="MyGeoPosition.com" version="1.1"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.topografix.com/GPX/1/1

http://www.topografix.com/GPX/1/1/gpx.xsd">

中国北京 东城区北京站东街北京 邮政编码: 100005 MyGeoPosition.com http://mygeoposition.com

标签中的lat属性设置纬度,lon属性设置经度。自己手写这个文件还是比较麻烦的,一般使用http://www.mygeoposition.com网站提供的GPX工具工具生成。这个网站免费提供地理信息编码和反编码、生成 KML 和 GPX 文件等服务。

GPX(GPS eXchange Format,GPS交换格式)是一个 XML 格式,是为应用软件设计的通用 GPS 数据格式。

得到 GPX 文件后,可以通过如图所示的Add GPX File to Project菜单项将它添加到 Xcode 工程中,此时在菜单中就会出现GPX文件了。如果我添加的文件名是test.gpx,则在菜单中出现 test 菜单项,选择 test 即可使用这个模拟坐标数据了。

iOS 系统自带定位服务_第13张图片

如果在应用启动参数中没有设置初始的模拟位置数据,我们还可以在运行之后设置。在调试工具栏中选择模 拟定位按钮,即可选择模拟位置,如图所示。

iOS 系统自带定位服务_第14张图片

Xcode 中的模拟器还提供了连续位置变化测试能力。如果想开发导航应用,这个功能对我们有很大的帮助。 此外,模拟器有几个固定的模式,可以发出连续变化的位置数据。打开模拟菜单的“调试”→“位置”,可以发 现共有7个菜单项,

iOS 系统自带定位服务_第15张图片

其中后面3个都能发出连续的位置变化数据,它们的起始点从苹果公司总部开始,按照一个固定的线路运动,这三者的区别是City Bicycle Ride是最慢的,City Run要快一些,Freeway Drive最快。

你可能感兴趣的:(iOS 系统自带定位服务)