定位服务:CoreLocation

23 9月

APP中的定位通过CoreLocation.framework来支持,IOS能通过多种方式(wifi,GPS,蓝牙)获取方向,经纬度,海拔等信息。

  • 定位权限
  • 定位信息

定位权限

因为定位涉及到用户隐私,需要用户允许。定位有两处开关:

一处是手机整体是否允许定位,通过以下方式引导用户跳转到手机settings界面:

[CLLocationManager locationServicesEnabled]

一处是具体某APP是否允许定位,可以设置【永不】【下次询问】【使用APP询问】【始终】,通过以下方式获取权限:

[CLLocationManager authorizationStatus]


询问用户是否允许的系统弹窗文案可以在info.plist里配置,例如询问用户是否允许在APP使用期间开启定位:

因为定位服务在整个APP中都可能被用到,通常设计成单例模式:

#import "Location.h"
#import <CoreLocation/CoreLocation.h>

@interface Location()
@property(nonatomic, strong, readwrite) CLLocationManager *manager;
@end

@implementation Location

// 实现成单例模式
+ (Location *)locationManager{
    static Location *location;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        location = [[Location alloc] init];
    });
    return location;
}

- (instancetype)init{
    self = [super init];
    if (self) {
        self.manager = [[CLLocationManager alloc] init];
    }
    return self;
}

- (void)checkLocationAuthorization{
    // 判断系统是否开启
    if(![CLLocationManager locationServicesEnabled]){
        // 引导弹窗
    }
    // 如果系统已经开启定位,看APP的定位权限是什么
    if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {  // 首次打开APP未指定定位权限
        [self.manager requestWhenInUseAuthorization];   // 询问用户是否允许:在APP使用期间使用定位服务,文案在info.plist里配置
    }
}

@end

当用户更改了APP的定位服务权限,需要在delegate中处理授权变化:

#import "Location.h"
#import <CoreLocation/CoreLocation.h>

@interface Location()<CLLocationManagerDelegate>
@property(nonatomic, strong, readwrite) CLLocationManager *manager;
@end

@implementation Location

...
- (instancetype)init{
    self = [super init];
    if (self) {
        self.manager = [[CLLocationManager alloc] init];
        self.manager.delegate = self;
    }
    return self;
}
...
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
    if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
        //    
    } else if (status == kCLAuthorizationStatusDenied) {
        //
    }
}
@end

定位信息

获得权限后,就可以通过CLLocationManager发起查询定位信息的请求,IOS会根据wifi,GPS,蓝牙等设备来查询你的位置信息,包括:CLLocation经纬度,CLPlacemark地标信息,CLGeocoder提供CLLocation与CLPlacemark之间的转换。

查询到信息后,通过delegate的回调获取:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
        ...
        [self.manager startUpdatingLocation];   // 申请获取当前定位信息(经纬度)
        
    } else if (status == kCLAuthorizationStatusDenied) {
        ...
    }
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation *location = [locations firstObject];
    CLGeocoder *coder = [[CLGeocoder alloc] init];
    
    [coder reverseGeocodeLocation:location completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {
        ... // 地标信息
    }];
    
    [self.manager stopUpdatingLocation];  // 获取后将服务关掉,不要一直开启
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注