地图(一)之CoreLocation
2019-02-28 本文已影响0人
陌巷先森
CoreLocation
CoreLocation用于地理定位,地理编码区域监听等(着重功能实现)
1.获取定位授权
iOS6+
- 当使用定位时用户会自动弹出对话框询问用户是否授权,当用户选择不允许,应用程序以后都不能获取定位权限
- 开发者可以在Info.plist中设置NSLocationUsageDescription说明定位的目的(Privacy - Location Usage Description)
iOS8+
1.系统不会主动请求定位,需要开发者通过代码请求授权
[_localManager requestWhenInUseAuthorization]; // 请求前台授权
[_localManager requestAlwaysAuthorization]; // 请求总是授权(前后台授权)
/*
注意:当设置为前台授权时,通过设置后台模式:location updates后 也可以后台获取定位信息,但是屏幕上方会出现蓝条
*/
2.开发者需要在Info.plist中配置对应的键值, 否则以上请求授权的方法不生效
- NSLocationAlwaysUsageDescription : 允许在前后台获取定位的描述
- NSLocationWhenInUseDescription : 允许在前台获取定位的描述
iOS9+
- 同样需要开发者通过代码请求授权及在Info.plist中配置对应的键值
[_localManager requestWhenInUseAuthorization]; // 请求前台授权
[_localManager requestAlwaysAuthorization]; // 请求总是授权(前后台授权)
/*
注意:当设置为前台授权时,除了设置后台模式:location updates,还要设置_localManager.allowsBackgroundLocationUpdates = YES,屏幕上方同样会出现蓝条
*/
- 新增API
-(void)requestLocation//单次请求用户位置
-(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations // 成功调用
-(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error // 失败调用
/*
注意:
(1) 必须实现代理的-locationManager:didFailWithError:方法
(2) 不能与startUpdatingLocation方法同时使用
*/
iOS11+
在info.plist中配置NSLocationWhenInUseUsageDescription和NSLocationAlwaysAndWhenInUsageDescription来实现前后台定位
2.CLLocationManager
CoreLocation框架中使用CLLocationManager对象来做用户定位
常用属性
//初始化CLLocationManager对象
_locationManger = [[CLLocationManager alloc] init];
//设置代理
_locationManger.delegate = self;
//设置定位精确度
_locationManger.desiredAccuracy = kCLLocationAccuracyBest;
//每隔多少米定位一次
_locationManger.distanceFilter = 100;
if (@available(iOS 8.0, *)) {
// 请求前台定位授权
[_locationManger requestWhenInUseAuthorization];
if (@available(iOS 9.0, *)) {
// iOS9.0+ 设置允许后台位置更新
_locationManger.allowsBackgroundLocationUpdates = YES;
}
}
常用方法
//开始定位
[self.locationManger startUpdatingLocation];
//开始监听设备朝向
[self.locationManger startUpdatingHeading];
//停止定位
[self.locationManger stopUpdatingLocation];
//停止监听设备朝向
[self.locationManger stopUpdatingHeading];
常用代理方法
//更新位置时调用
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
NSLog(@"更新定位了");
}
//更新朝向时调用
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
}
//进入区域时调用
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(@"进入%@附近100米",region.identifier);
}
//离开区域时调用
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
NSLog(@"离开%@附近100米",region.identifier);
}
//判断是否在某个区域时的状态
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
NSLog(@"%zd", state);
}
//授权状态改变时调用
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
NSLog(@"用户未决定(请求授权之前的状态)");
break;
case kCLAuthorizationStatusRestricted:
NSLog(@"访问受限制");
break;
case kCLAuthorizationStatusDenied: // 定位关闭时和对此APP授权为never时调用
if([CLLocationManager locationServicesEnabled]){
// 定位服务开启了
NSLog(@"永不或者不允许Not Allow");
} else {
NSLog(@"定位服务关闭了");
// 先允许定位,然后关闭掉定位服务,再开始定位startUpdatingLocation时系统会弹出设置定位服务打开弹框
}
break;
case kCLAuthorizationStatusAuthorizedAlways://
NSLog(@"始终:前后台");
break;
case kCLAuthorizationStatusAuthorizedWhenInUse://
NSLog(@"应用使用期间:前台");
break;
default:
break;
}
}
3.CLLocation
CLLocation对象用来存储CLLocationManager对象生成的位置数据
常用属性
CLLocation *location = [locations lastObject];
CLLocationCoordinate2D coordinate = location.coordinate;//经纬度
CGFloat altitude = location.altitude;//海拔
CGFloat horizontalAccuracy = location.horizontalAccuracy; // 水平精度,如果值是复数代表无效
CGFloat verticalAccuracy = location.verticalAccuracy; // 垂直精度,如果值是复数代表无效
CGFloat course = location.course;//方向
CGFloat speed = location.speed;//速度
4.CLGeocoder
CLGeocoder对象用于处理地理编码和反地理编码功能
//地理编码
-(void)getCoordinateByAddress{
[self.geocoder geocodeAddressString:self.addressField.text completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
//取得第一个地标,地标中存储了详细的地址信息,注意:一个地名可能搜索出多个地址
CLPlacemark *placemark = [placemarks firstObject];
}];
}
//反地理编码
-(void)getAddress{
CLLocation *location = [[CLLocation alloc] initWithLatitude:self.latitudeField.text.doubleValue
longitude:self.longitudeField.text.doubleValue];
[self.geocoder reverseGeocodeLocation:location
completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks firstObject];
}];
}
5.CLPlacemark
CLPlacemark对象代表一个地标,存储了详细的地址信息
具体属性
//以下为CLPlacemark中包含的信息
CLLocation *location = placemark.location;//位置
CLRegion *region = placemark.region;//区域
NSTimeZone * timezone = placemark.timeZone;//时区
NSDictionary *addressDic = placemark.addressDictionary;//详细地址信息字典
NSString *name = placemark.name;//地名
NSString *thoroughfare = placemark.thoroughfare;//街道
NSString *subThoroughfare = placemark.subThoroughfare; //街道相关信息,例如门牌等
NSString *locality = placemark.locality; // 城市
NSString *subLocality = placemark.subLocality; // 城市相关信息,例如标志性建筑
NSString *administrativeArea = placemark.administrativeArea; // 州
NSString *subAdministrativeArea = placemark.subAdministrativeArea; //其他行政区域信息
NSString *postalCode = placemark.postalCode; //邮编
NSString *ISOcountryCode = placemark.ISOcountryCode; //国家编码
NSString *country = placemark.country; //国家
NSString *inlandWater = placemark.inlandWater; //水源、湖泊
NSString *ocean = placemark.ocean; // 海洋
NSArray *areasOfInterest = placemark.areasOfInterest; //关联的或利益相关的地标
参考:完整项目资料下载