关于 Core Location 的笔记

来源:互联网 发布:java 从url去掉ip地址 编辑:程序博客网 时间:2024/06/06 16:45

最近项目中遇到需要通过MKMapView和CLLocation进行定位和商铺显示的需求,这几天把这些零散的知识点总结了一下,方便日后回顾。这篇博文主要先回顾Core Location相关内容。

先双手奉上demo代码。

演示效果

01.gif02.gif

Core Location是iOS2.0及之后用来定位的框架,在iOS3.0后加入了定位手机方向的API。Core Location能够定位到用户的位置靠的是Wifi定位,蜂窝基站定位和GPS定位。具体的定位方式不需要开发者考虑,iPhone会根据不同场景选择不同定位方式。

那下面我们就来用示例程序看一下在项目中Core Location应该怎么结合进去。

CLLocationManager

首先,我们需要创建一个CLLocation服务的管理者CLLocationManager,设置代理。(当然,在这之前需要导入头文件CoreLocation/CoreLocation.h)

1
2
self.locMgr = [[CLLocationManager alloc] init];
self.locMgr.delegate = self;

我们可以使用startUpdatingLocation和stopUpdatingLocation来开始和结束定位.

1
2
[self.locMgr startUpdatingLocation];
[self.locMgr stopUpdatingLocation];

当成功获取到用户位置时,会通过回调函数通知控制器(调用频率非常频繁,在适当的时候应调用stopUpdatingLocation方法停止更新用户位置或者设置CLLocationManager的distanceFilter属性来对距离的改变进行筛选,即筛选设定距离以内的变化不会产生回调)

1
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;

我们还可以通过设置desiredAccuracy属性来设置定位精度,我们可以将精度设为以下常量:

1
2
3
4
5
6
extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation;
extern const CLLocationAccuracy kCLLocationAccuracyBest;
extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;
extern const CLLocationAccuracy kCLLocationAccuracyKilometer;
extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;

大概第一步完成是这样子的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@interface ViewController ()
@property (strong, nonatomic) CLLocationManager *locMgr;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
     
    self.locMgr = [[CLLocationManager alloc] init];
    self.locMgr.delegate = self;
    self.locMgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    self.locMgr.distanceFilter = 50;
    [self.locMgr startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    NSLog(@"%@", locations);
}
@end

运行程序,却出现了一个问题,在iOS7上会弹出询问用户是否允许导航的提示,但是在iOS8中却不会出现。

cllocation img1.png

提示

或许是因为iOS8对安全的要求更严格了(是因为iCloud泄密出去艳照的原因?),需要开发者通过代码手动去请求定位许可(WhenInUseAuthorization或AlwaysAuthorization):

1
2
3
4
5
6
7
8
9
if ([self.locMgr respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locMgr requestWhenInUseAuthorization];
//    [self.locMgr requestAlwaysAuthorization];
}
         
//    也可以判断当前系统版本是否大于8.0,大于8.0时进行请求
//    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
//    [self.locMgr requestWhenInUseAuthorization];
//    }

光这样设置了还不够,运行程序依然没办法获得提示,我们需要到Info.plist里面配置一下(添加一项NSLocationWhenInUseUsageDescription或NSLocationAlwaysUsageDescription,根据不同项目需要选择)

cllocation img2.png

配置完成后就能够在iOS8下看到提示了。

定位授权判断

在使用时我们需要判断程序定位功能是否被开启要怎么做呢?我们使用系统提供的[CLLocationManager locationServicesEnabled]这个方法。。。当然是不行的!!!这个方法仅仅判断了系统的定位服务是否开启,不能判断应用,所以我用了下面的方法进行判断:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 *  判断定位授权
 */
- (void)locationAuthorizationJudge {
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
     
    if (status == kCLAuthorizationStatusNotDetermined) {
        // 如果授权状态还没有被决定就弹出提示框
    else if (status == kCLAuthorizationStatusDenied) { 
        // 如果授权状态是拒绝就给用户提示
    else if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusAuthorizedAlways) {
        // 如果授权状态可以使用就开始获取用户位置
    }
}

地理编码与反地理编码

地理编码主要用于把用户输入的内容转换成详细坐标的方法,而反地理编码则是通过输入经纬度来获取相对应的位置信息。两者的实现都需要地理编码器CLGeocoder。

在介绍地理编码与反地理编码之前先说下CLPlacemark这个类。从名称就可以看出,CLPlacemark是用来表示地标的类,包含的参数有:cllocation,name(地标名),addressDictionary(A dictionary containing the Address Book keys and values for the placemark),country,locality等等。

1
- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;

地理编码调用方法,返回一个placemarks的数组和一个NSError的对象。数组中存放的是CLPlacemark的对象。为什么会返回一个数组?因为同名的地方可能会有多个,例如“帝都”:

cllocation img3.png

1
- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;

至于反地理编码,可以调用这个方法,将具体的经纬度坐标整合成CLLocation对象,和地理编码一样,完成后也会返回一个placemarks的数组和一个NSError的对象。具体效果看前面的演示吧。

模拟器定位

关于模拟器定位我这边的做法是给一个默认的位置,这个可以按照下图进行设置,我选的模拟位置是香港。

cllocation img4.png

cllocation img5.png

部分需要配合真机测试的一些功能在这里就不展开了,感兴趣的童鞋可以研究下。

0 0
原创粉丝点击