iOS地图之CoreLocation框架
首先介绍一点小常识:iOS6.0以后,苹果在用户隐私方面做了加强,访问一些隐私信息(例如位置,相册,联系人等)时必须通过用户的批准,系统自动弹出提醒框,询问用户是否同意;但是在iOS8.0之后不再自动弹出,程序员手动设置,infor.plist文件中添加字段:NSLocationWhenInUseUsageDescription使用的时候访问,默认情况下后台不能获取位置;
NSLocationAlwaysUsageDescription一直访问,后台可以获取位置;地图定位越精确,越耗电,定位时间越长。
CoreLocation框架在地图中用于定位:
1 #import "ViewController.h"
2 //引入库的头文件
3 #import <CoreLocation/CoreLocation.h>
4 @interface ViewController ()<CLLocationManagerDelegate>
5 ///定位管理器,用于地图定位功能的实现
6 @property (nonatomic, strong) CLLocationManager *manager;
7
8 ///编码反编码的类(根据地名获取该地的经纬度,根据经纬度获取该地的地名)
9 @property (nonatomic, strong) CLGeocoder *geocoder;
10
11 @end
12
13 @implementation ViewController
14
15 //懒加载,第一步:初始化定位管理器:这些步骤的先后顺序不是固定的
16 //懒加载的好处:防止使用前创建,节省内存;防止重复创建;防止对象使用时还没有创建;在懒加载中进行初始化,降低代码的耦合性。
17 - (CLLocationManager *)manager {
18 if (!_manager) {
19 _manager = [[CLLocationManager alloc] init];
20 _manager.delegate = self;
21 }
22 return _manager;
23 }
24
25 - (void)viewDidLoad {
26 [super viewDidLoad];
27 //定位步骤
28 //第二步:进行隐私设置,是否授权允许定位
29 if (![CLLocationManager locationServicesEnabled]) {
30 NSLog(@"是否允许定位");
31 }
32 /*
33 定位服务授权状态,返回枚举类型:
34 kCLAuthorizationStatusNotDetermined: 用户尚未做出决定是否启用定位服务
35 kCLAuthorizationStatusRestricted: 没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权
36 kCLAuthorizationStatusDenied :用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态
37 kCLAuthorizationStatusAuthorizedAlways: 应用获得授权可以一直使用定位服务,即使应用不在使用状态
38 kCLAuthorizationStatusAuthorizedWhenInUse: 使用此应用过程中允许访问定位服务*/
39 //第三步:根据状态进行授权(可选的要进行版本的判断)
40 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
41 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) {
42 //在请求授权之前需要在info.plist中设置定位内容:NSLocationWhenInUseUsageDescription,在使用的时候允许定位,默认不支持后台定位,若要支持后台需要使用下面一句代码,并且按图片设置工程。
43 //info.plist中设置定位内容是NSLocationAlwaysUsageDescription时,支持后台定位。
44 self.manager.allowsBackgroundLocationUpdates = YES;//
45 }//在请求授权之前需要在info.plist中设置定位内容:NSLocationWhenInUseUsageDescription
46 //请求授权
47 [self.manager requestWhenInUseAuthorization];
48 }
49 //第四步:相关属性
50 //设置精度
51 self.manager.desiredAccuracy = 100;
52 //每隔100米定位一次
53 self.manager.distanceFilter = 100;
54 //设置最小更新距离
55 self.manager.distanceFilter = 100;
56 //第五步:开启定位
57 [self.manager startUpdatingLocation];
58
59 /**************************编码与反编码*****************************/
60 //初始化对象
61 self.geocoder = [[CLGeocoder alloc] init];
62 //自定义方法,根据地名获取经纬度
63 //[self getCoordinateByAddress:@"北京"];
64
65 //根据经纬度反编码取出地名:注意,编码和反编码不能写在一个方法中,若要执行该命令,将上一句根据地名取出经纬度的方法注掉。
66 [self getAddressByLongitude:116 Latitude:40];
67
68 //计算两点之间的距离
69 [self distence];
70 }
71
72 #pragma mark - 计算两个地方之间的距离
73 - (void)distence {
74 //创建位置1、2
75 CLLocation *locationBeiJing = [[CLLocation alloc] initWithLatitude:40 longitude:116];
76 CLLocation *locationDaLian = [[CLLocation alloc] initWithLatitude:39 longitude:121];
77
78 CLLocationDistance distence = [locationBeiJing distanceFromLocation:locationDaLian];
79 NSLog(@"北京到大连的距离%f", distence);
80
81 }
82
83 #pragma mark - 根据经纬度获取地名
84 - (void)getAddressByLongitude:(CLLocationDegrees)longitude Latitude:(CLLocationDegrees)latitude {
85 //反编码
86 CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
87 [_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
88 NSDictionary *dict = placemarks.firstObject.addressDictionary;
89
90 NSLog(@"反编码地理位置信息:%@", dict);
91
92 }];
93 }
94
95 #pragma mark - 根据地名获取相关的信息
96 - (void)getCoordinateByAddress:(NSString *)address {
97 //编码方法
98 [_geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
99 //根据返回的地标,取出第一个位置的元素
100 CLPlacemark *mark = placemarks.firstObject;
101 //根据mark得到location
102 CLLocation *location = mark.location;
103 //根据mark获取区域
104 CLRegion *region = mark.region;
105 //获取字典信息
106 NSDictionary *addressDict = mark.addressDictionary;
107 NSLog(@"地标:%@, location:%@,区域: %@, 字典:%@", mark, location, region, addressDict);
108
109 }];
110 }
111
112 #pragma mark - CLLocationManagerDelegate的代理方法
113 //这个代理方法是定位成功之后开始更新位置的信息,只要移动设置的最小距离之后就开始
114 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
115 //获取最后一次定位的位置信息
116 CLLocation *location = locations.lastObject;
117 CLLocationCoordinate2D coordinate = location.coordinate;
118 NSLog(@"经度:%f,纬度:%f,海拔:%f,航向:%f,速度:%f", coordinate.longitude, coordinate.latitude, location.altitude, location.course, location.speed);
119 //为例节省电量,如果不使用定位,就将定位关掉
120 [self.manager stopUpdatingLocation];
121 /*
122 注意:
123 1.定位频率和定位精度并不应当越精确越好,需要视实际情况而定,因为越精确越耗性能,也就越费电。
124 2.定位成功后会根据设置情况频繁调用-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations方法,这个方法返回一组地理位置对象数组,每个元素一个CLLocation代表地理位置信息(包含经度、纬度、海报、行走速度等信息),之所以返回数组是因为有些时候一个位置点可能包含多个位置。
125 3.使用完定位服务后如果不需要实时监控应该立即关闭定位服务以节省资源。
126 4.除了提供定位功能,CLLocationManager还可以调用startMonitoringForRegion:方法对指定区域进行监控。
127 */
128
129 }
130 //定位失败走这个方法
131 - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
132
133 NSLog(@"定位失败:%@", error);
134
135 }
136 @end
第35行代码: //在请求授权之前需要在info.plist中设置定位内容:NSLocationWhenInUseUsageDescription
图示:
运行工程弹出提醒框: