当App需要用户的位置信息时,我们可以体统自带的CoreLocation
来获取,接下来就是所有的流程。
1.准备工作
1.1. 在info.plist 添加
Privacy - Location Always Usage Description
或者Privacy - Location When In Use Usage Description
权限,类型为String,value中一定要有值, 来告诉用户使用定位服务的目的(一直定位/当用户使用时定位)
1.2.在程序的
Build Phases
的Link Binary With Libraries
导入CoreLocation.framework
2.导入.m文件中,申请权限
在系统刚启动时申请获取用户信息的权限,在AppDelegate.m 中申请使用用户的地理位置权限,具体在哪需要地理位置信息,那就在哪实现获取地理位置的相关代理。
下面的🌰是在AppDelegate.m 中申请的地理位置权限 ,在BaseController里实现代理方法。
@interface AppDelegate () <DBSessionDelegate,CLLocationManagerDelegate> //添加代理
@property (nonatomic, strong) CLLocationManager *cllocationManager;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [UIViewController new];
[self.window makeKeyAndVisible];
[self getUserLocation];
return YES;
}
- (void) getUserLocation {
int status=[CLLocationManager authorizationStatus];
if (![CLLocationManager locationServicesEnabled] || status < 3) {
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
_cllocationManager = [[CLLocationManager alloc] init];
[_cllocationManager requestAlwaysAuthorization];
[_cllocationManager requestWhenInUseAuthorization];
}
}
}
// 如果在Appdelegate中需要地理位置,那么在这实现代理方法来获取地理位置信息
@end
在BaseController.m使用时实现代理方法
#import "BaseController.h"
#import <CoreLocation/CoreLocation.h>
@interface BaseController ()<CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *locMgr;
@end
@implementation BaseController
#pragma mark-懒加载
- (CLLocationManager *)locMgr {
if (_locMgr==nil) {
//1.创建位置管理器(定位用户的位置)
_locMgr=[[CLLocationManager alloc]init];
//2.设置代理
_locMgr.delegate=self;
}
return _locMgr;
}
- (void)viewDidLoad {
[super viewDidLoad];
//判断用户定位服务是否开启
if ([CLLocationManager locationServicesEnabled]) {
//开始定位用户的位置
[self.locMgr startUpdatingLocation];
//每隔多少米定位一次(这里的设置为任何的移动)
self.locMgr.distanceFilter=kCLDistanceFilterNone;
//设置定位的精准度,一般精准度越高,越耗电(这里设置为精准度最高的,适用于导航应用)
self.locMgr.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
} else {
//不能定位用户的位置
//1.提醒用户检查当前的网络状况
//2.提醒用户打开定位开关
}
//测试方法,计算两个位置之间的距离
[self countDistance];
}
#pragma mark - CLLocationManagerDelegate
/**
* 当定位到用户的位置时,就会调用(调用的频率比较频繁)
*/
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
//locations数组里边存放的是CLLocation对象,一个CLLocation对象就代表着一个位置,获取最后的一个位置
CLLocation *currentLocation = [locations lastObject];
//当定位成功后,如果horizontalAccuracy大于0,说明定位有效 horizontalAccuracy,该位置的纬度和经度确定的圆的中心,并且这个值表示圆的半径。负值表示该位置的纬度和经度是无效的
//维度:currentLocation.coordinate.latitude
//经度:currentLocation.coordinate.longitude
CLLocationCoordinate2D coor = currentLocation.coordinate;
NSDictionary *location = @{@"latitude":@(coor.latitude),@"longitude":@(coor.longitude),@"horizontalAccuracy":@(currentLocation.horizontalAccuracy)};
[PBCacheUtil setUserLocation:location];
//停止更新位置(如果定位服务不需要实时更新的话,那么应该停止位置的更新)
[self.locMgr stopUpdatingLocation];
}
//获取地理位置失败,赋予默认值
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(nonnull NSError *)error {
NSDictionary *location = @{@"latitude":@(0.000000),@"longitude":@(0.000000),@"horizontalAccuracy":@(0.000000)};
[PBCacheUtil setUserLocation:location];
}
//计算两个位置之间的距离
-(void)countDistance {
//根据经纬度创建两个位置对象
CLLocation *loc1=[[CLLocation alloc]initWithLatitude:40 longitude:116];
CLLocation *loc2=[[CLLocation alloc]initWithLatitude:41 longitude:116];
//计算两个位置之间的距离
CLLocationDistance distance=[loc1 distanceFromLocation:loc2];
NSLog(@"(%@)和(%@)的距离=%fM",loc1,loc2,distance);
}
@end