平时我们再写程序的时候经常会需要访问当前设备的位置信息和计算当前位置距某点的距离,下面我来为大家浅谈一下使用OC自带的库来获取当前坐标和其的距离计算。
一、获取当前经纬度坐标
步骤1:添加关键字
首先要Info 里添加两个键值对,向用户请求位置服务时会显示在这里设置的值的内容。
<key>NSLocationWhenInUseUsageDescription</key>
<value>使用程序的时候获取本机位置</value>
<key>NSLocationAlwaysUsageDescription</key>
<value>总是获取本机位置</value>
步骤2:导入头文件
#import <CoreLocation/CoreLocation.h>
这个是OC自带的一个库,不需要再导入其他的第三方库了。
步骤3:遵循相关协议
<CLLocationManagerDelegate>
因为我们需要使用到其相关的协议函数来实现,所以我们需要遵循其相关协议。
步骤4:设置属性,开始定位
我们在开始定位之前需要设置一个定位管理者的属性,并且它只能设置为属性,当你没设置属性的时候,软件开启时提示定位的提示出现一瞬间就消失了。
@property (nonatomic, strong) CLLocationManager *locationManager;
如果你只想获取当前经纬度坐标的话定义一个这个就足够了,若是你还想获取当前位置的更多信息那么你还需要再设置一个下面这个属性:
@property (nonatomic, strong) CLGeocoder *geoCoder;
这个属性用于获取通过当前位置坐标推算出来的更多的位置信息,比如市、区、名字等等。 定义完属性之后,下面开始定位:
- (void)startLocation {
self.locationManager = [[CLLocationManager alloc] init];
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
self.geoCoder = [[CLGeocoder alloc] init];
} else {
NSLog(@"error");
}
}
CLLocationManager 其相关的属性:
desiredAccuracy 位置的精度属性,取值有如下几种:
kCLLocationAccuracyBest | 精确度最佳 |
---|
kCLLocationAccuracynearestTenMeters | 精确度10m以内 | kCLLocationAccuracyHundredMeters | 精确度100m以内 | kCLLocationAccuracyKilometer | 精确度1000m以内 | kCLLocationAccuracyThreeKilometers | 精确度3000m以内 |
delegate :响应CLLocationManagerdelegate 的对象 distanceFilter :横向移动多少距离后更新位置信息
步骤5:在对应的代理方法中获取到我们需要的位置信息
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations 在此代理方法中我们可以获取到当前位置的经纬度。 注意: locations 是一个数组类型,它的最后一个元素就是我们获取的经纬度坐标,其类型为CLLocation ,我们如果想将其设为属性其修饰符一定要是retain 。 下面我定义了一个属性来存储获取到的位置信息:
@property (nonatomic, retain) CLLocation *myLocation;
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
NSLog(@"%lu", (unsigned long)locations.count);
self.myLocation = locations.lastObject;
NSLog(@"经度:%f 纬度:%f", _myLocation.coordinate.longitude, _myLocation.coordinate.latitude);
[self.geoCoder reverseGeocodeLocation:self.myLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(@"%@", placemark.name);
NSString *city = placemark.locality;
if (!city) {
city = placemark.administrativeArea;
}
NSLog(@"name, %@", placemark.name);
NSLog(@"thoroughfare, %@", placemark.thoroughfare);
NSLog(@"subThoroughfare, %@", placemark.subThoroughfare);
NSLog(@"locality, %@", placemark.locality);
NSLog(@"subLocality, %@", placemark.subLocality);
NSLog(@"country, %@", placemark.country);
} else if (error == nil && [placemarks count] == 0) {
NSLog(@"No results were returned.");
} else if (error != nil) {
NSLog(@"An error occurred = %@", error);
}
}];
[self.locationManager stopUpdatingLocation];
}
当然不止这些,当获取位置信息出错时,我们会调用下面的协议:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
if (error) {
NSLog(@"error:%ld", (long)error.code);
}
}
以上就是获取本机当前位置信息的方法了。
二、测算距离
测算两个经纬度坐标之间的距离是非常简单的,并且该库中自带其计算的方法:- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
CLLocation *before = [[CLLocation alloc] initWithLatitude:39.91667 longitude:116.41667];
CLLocationDistance meters = [self.myLocation distanceFromLocation:before];
NSLog(@"相距:%fm", meters);
三、小小的代码测试
ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface ViewController : UIViewController<CLLocationManagerDelegate>
@end
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) CLGeocoder *geoCoder;
@property (nonatomic, retain) CLLocation *myLocation;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
self.myLocation = [[CLLocation alloc] init];
[self startLocation];
}
- (void)startLocation {
self.locationManager = [[CLLocationManager alloc] init];
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
self.geoCoder = [[CLGeocoder alloc] init];
} else {
NSLog(@"error");
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
NSLog(@"%lu", (unsigned long)locations.count);
self.myLocation = locations.lastObject;
NSLog(@"经度:%f 纬度:%f", _myLocation.coordinate.longitude, _myLocation.coordinate.latitude);
CLLocation *before = [[CLLocation alloc] initWithLatitude:39.91667 longitude:116.41667];
CLLocationDistance meters = [self.myLocation distanceFromLocation:before];
NSLog(@"相距:%fm", meters);
[self.geoCoder reverseGeocodeLocation:self.myLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(@"%@", placemark.name);
NSString *city = placemark.locality;
if (!city) {
city = placemark.administrativeArea;
}
NSLog(@"name, %@", placemark.name);
NSLog(@"thoroughfare, %@", placemark.thoroughfare);
NSLog(@"subThoroughfare, %@", placemark.subThoroughfare);
NSLog(@"locality, %@", placemark.locality);
NSLog(@"subLocality, %@", placemark.subLocality);
NSLog(@"country, %@", placemark.country);
} else if (error == nil && [placemarks count] == 0) {
NSLog(@"No results were returned.");
} else if (error != nil) {
NSLog(@"An error occurred = %@", error);
}
}];
[self.locationManager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
if (error) {
NSLog(@"error:%ld", (long)error.code);
}
}
@end
over!
|