今天来说下iOS定位中的那些事,咱们闲话少叙,直奔主题。
最近在做和定位有关的业务,索性就又研究了一下iOS 10系统级的定位功能(之前也做过和定位相关的app),从iOS 8以后,我们引用系统级的功能都要去在info.plsit中去设置访问权限,定位的权限:
权限一:
NSLocationAlwaysUsageDescription
应用需要访问定位(始终)
权限二:
NSLocationWhenInUseUsageDescription
应用需要访问定位(在使用期间)
当然我们把这两个权限全部添加进去也是可以的,我们值需要在初始化定位的时候告诉定位管理器,是按那种权限访问的就ok,比如:
//使用应用程序期间允许访问位置数据
[self.locationManagerrequestWhenInUseAuthorization];
这样就是在打开应用期间访问定位。
首先,我们先来创建一个定位管理器LocationManager,在LocationManager.h文件里面声明一些方法和变量,如下:
#import"LocationModel.h"
@interfaceLocationManager :NSObject
@property(nonatomic,strong)LocationModel*location;
//开始定位
- (void)beginUpdatingLocation;
//结束定位
- (void)stopLocationService;
//设置定位精度(这个属性依使用情况而定,如果要求不是很高的,只是用定位就不要设置高经度,设置的经度越高,系统越耗电)
-(double)setDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy;
//设置每隔多少米定位一次
- (double) setDistanceFilter :(CLLocationDistance)distanceFilter;
+ (LocationManager*)shareLocation;
@end
现在可以在LocationManager.m文件去实现:
#import "LocationManager.h"
@interface LocationManager()
@property (nonatomic, strong) CLLocationManager * locationManager;
@end
@implementation LocationManager
+ (LocationManager *)shareLocation
{
static LocationManager *location = nil;
static dispatch_once_t once;
dispatch_once(&once, ^{
location = [[LocationManager alloc] init];
});
return location;
}
/******************************************************************************
**** beginUpdatIngLocation Method ****
******************************************************************************/
#pragma mark -
#pragma mark beginUpdatIngLocation Method
//开始定位
- (void)beginUpdatingLocation
{
//判断定位操作是否被允许
if([CLLocationManager locationServicesEnabled] == YES)
{
self.locationManager = [[CLLocationManager alloc] init] ;
self.locationManager.delegate = self;
//使用应用程序期间允许访问位置数据
[self.locationManager requestWhenInUseAuthorization];
// 开始定位
[self.locationManager startUpdatingLocation];
}
}
//typedef NS_ENUM(int, CLAuthorizationStatus) {
// kCLAuthorizationStatusNotDetermined = 0,//用户还没有做选择
// kCLAuthorizationStatusRestricted,//应用拒接使用定位服务
// kCLAuthorizationStatusDenied,//用户拒绝授权
// kCLAuthorizationStatusAuthorizedAlways,//8.0后可用,始终授权位置服务
// kCLAuthorizationStatusAuthorizedWhenInUse,//8.0后可用,只在前台授权位置服务
//};
//停止定位
- (void)stopLocationService
{
[self.locationManager stopUpdatingLocation];
[self.locationManager setDelegate: nil];
}
//定位失败展现提示框
- (void)showAlertView
{
UIAlertView *alertV = [[UIAlertView alloc]initWithTitle:@"提示"
message:@"定位服务当前可能尚未打开,请在设置中打开定位!"
delegate:self
cancelButtonTitle:@"取消"
otherButtonTitles:@"设置", nil];
alertV.tag = 1000;
[alertV show];
}
- (void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 1000)
{
if (buttonIndex == 0)
{
return;
}
else if (buttonIndex == 1)
{
//定位服务设置界面
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
}
}
}
}
/******************************************************************************
**** location Delegate Method ****
******************************************************************************/
#pragma mark -
#pragma mark location Delegate Method
//定位成功,获取地理位置
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
//系统会一直更新数据,直到选择停止更新,因为我们只需要获得一次经纬度即可,所以获取之后就停止更新
[self stopLocationService];
//获取新的位置
CLLocation * newLocation = [locations lastObject];
//创建自定制位置对象
LocationModel *oneLocation = [[LocationModel alloc] init];
//存储经度
oneLocation.longitude = newLocation.coordinate.longitude;
//存储纬度
oneLocation.latitude = newLocation.coordinate.latitude;
//获取当前所在的城市名
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
//根据经纬度反向地理编译出地址信息
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error)
{
if (placemarks.count >0 && error == nil)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//获取城市
//存储位置信息
oneLocation.country = String(placemark.country);
oneLocation.administrativeArea = String(placemark.administrativeArea);
oneLocation.subLocality = String(placemark.subLocality);
oneLocation.thoroughfare = String(placemark.thoroughfare);
oneLocation.subThoroughfare = String(placemark.subThoroughfare);
oneLocation.locality = String(placemark.locality);
oneLocation.concreteAdd = String(placemark.name);
if (!oneLocation.locality)
{
//四大直辖市的城市信息无法通过locality获得,只能通过获取省份的方法来获得(如果city为空,则可知为直辖市)
oneLocation.locality = String(placemark.administrativeArea);
}
self.location = oneLocation;
}
if (error != nil || placemarks.count == 0)
{
NSLog(@"No results were returned or An error occurred = %@", error);
return ;
}
}];
}
// 代理方法中监听授权的改变,被拒绝有两种情况,一是真正被拒绝,二是服务关闭了
//- (void)locationManager:(CLLocationManager *)manager
//didChangeAuthorizationStatus:(CLAuthorizationStatus)status
//{
// switch (status)
// {
// case kCLAuthorizationStatusNotDetermined:
// {
// NSLog(@"用户未决定");
// break;
// }
// // 系统预留字段,暂时还没用到
// case kCLAuthorizationStatusRestricted:
// {
// NSLog(@"受限制");
// break;
// }
// case kCLAuthorizationStatusDenied:
// {
// // 被拒绝有两种情况 1.设备不支持定位服务 2.定位服务被关闭
// if ([CLLocationManager locationServicesEnabled]) {
// NSLog(@"真正被拒绝");
// // 跳转到设置界面
//// [self showAlertView];
// }
// else {
// NSLog(@"没有开启此功能");
// }
// break;
// }
// case kCLAuthorizationStatusAuthorizedAlways:
// {
// NSLog(@"前后台定位授权");
// break;
// }
// case kCLAuthorizationStatusAuthorizedWhenInUse:
// {
// NSLog(@"前台定位授权");
// break;
// }
//
// default:
// break;
// }
//}
//定位失败
-(void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
self.location = nil;
//[self showAlertView];
}
//设置过滤器
- (double)setDistanceFilter:(CLLocationDistance)distanceFilter
{
NSLog(@"过滤器:%lf",distanceFilter);
return _locationManager.distanceFilter = distanceFilter;
}
//设置定位精度
- (double)setDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy
{
NSLog(@"定位精度:%lf",desiredAccuracy);
return _locationManager.desiredAccuracy = desiredAccuracy;
}
@end
数据的model:
#import
#import
@interface LocationModel : NSObject
//国家
@property (nonatomic, copy) NSString * country;
//省 直辖市
@property (nonatomic, copy) NSString * administrativeArea;
//地级市 直辖市区
@property (nonatomic, copy) NSString * locality;
//县 区
@property (nonatomic, copy) NSString * subLocality;
//街道
@property (nonatomic, copy) NSString * thoroughfare;
//子街道
@property (nonatomic, copy) NSString * subThoroughfare;
//具体地址: xx市xx区xx街道
@property (nonatomic, copy) NSString *concreteAdd;
//经度
@property (nonatomic, assign) CLLocationDegrees longitude;
//纬度
@property (nonatomic, assign) CLLocationDegrees latitude;
//海拔
@property (nonatomic,assign) CLLocationDistance altitude;
//航向
@property (nonatomic,assign) CLLocationDirection course;
//行走速度
@property (nonatomic,assign) CLLocationDegrees speed;
@end
以上,就是今天给大家分享的关于ios定位的那些事,希望可以帮助到大家,谢谢!