定位
常用方法的介紹
CLLocationManager位置管理器,我們的有關(guān)于位置的方法和屬性都是通過它來管理設(shè)置的。
+ (BOOL)locationServicesEnabled監(jiān)測(cè)設(shè)備是否開啟定位功能。
- (void)requestAlwaysAuthorization請(qǐng)求用戶設(shè)置在程序運(yùn)行期間和程序在前臺(tái)和后臺(tái),都開啟定位。需要在info.plist文件中添加相應(yīng)的字段(鍵值對(duì))來配合該方法的使用。NSLocatiodenAlwaysUsageDescription鍵 值(提示信息)
- (void)requestWhenInUseAuthorization請(qǐng)求用戶設(shè)置只在程序運(yùn)行期間才開啟定位服務(wù)。需要在info.plist文件中添加相應(yīng)的字段(鍵值對(duì))來配合該方法的使用。NSLocationWhenInUseUsageDescription鍵 值(提示信息)
- (void)startUpdatingLocation開啟定位,在所有相關(guān)的屬性設(shè)置完畢之后,需要開啟定位。
需要設(shè)置的屬性
- 設(shè)置定位的頻率,每隔多少米定位一次。
距離篩選器
@property(assign, nonatomic) CLLocationDistance distanceFilter;
如果將下面的常量賦值給這個(gè)屬性就可以將位置管理器返回到?jīng)]有設(shè)置篩選器的默認(rèn)狀態(tài)。
- 設(shè)置精確度(精確度是根據(jù)當(dāng)前應(yīng)用的需求來定的,不是越精確越好,精確度越高越耗電)。
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
//下面是可以被設(shè)置的值
extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation;
extern const CLLocationAccuracy kCLLocationAccuracyBest;
extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;
extern const CLLocationAccuracy kCLLocationAccuracyKilometer;
extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;
- CLLocationManager代理屬性,用來指定代理人。
@property(assign, nonatomic, nullable) id<CLLocationManagerDelegate> delegate;
示例代碼
注意:在初始化位置管理器的時(shí)候,我們需要將位置管理器的對(duì)象設(shè)置成為實(shí)例變量或者是屬性,如果直接初始化為局部實(shí)例變量,這時(shí)候它的協(xié)議方法有可能會(huì)不執(zhí)行。
在代碼都正常的情況下,定位如果失敗,有可能是網(wǎng)絡(luò)環(huán)境的問題,我們可以換一下網(wǎng)絡(luò)試試
在延展中需要聲明屬性
@interface RootViewController ()<CLLocationManagerDelegate>
@property (strong, nonatomic)CLLocationManager *locationManager;//定位服務(wù)的管理對(duì)象。
@end
self.locationManager = [[CLLocationManager alloc]init];初始化一個(gè)位置管理器
BOOL openLocationServices = [CLLocationManager locationServicesEnabled];
if (openLocationServices) {
NSLog(@"已經(jīng)開啟定位");
[self.locationManager requestAlwaysAuthorization];//請(qǐng)求用戶總是使用定位服務(wù)
self.locationManager.distanceFilter = 10.0;//設(shè)置定位的頻率,
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//設(shè)置精確度
self.locationManager.delegate = self;//設(shè)置代理
[self.locationManager startUpdatingLocation];//開始定位
}else{
NSLog(@"無法獲取你的位置信息,為了更好的為你服務(wù),請(qǐng)?jiān)谠O(shè)置隱私定位服務(wù)中開啟定位服務(wù)");
}
定位的代理方法
位置管理器代理必須遵循CLLocationManagerDelegate協(xié)議,該協(xié)議定義了多個(gè)方法,其中有兩個(gè)方法,當(dāng)位置管理器已經(jīng)確定當(dāng)前位置或者當(dāng)它檢測(cè)到位置的更改時(shí)將調(diào)用。
在方法中你會(huì)見到一個(gè)CLLocationCoordinate2D它是一個(gè)結(jié)構(gòu)體,里面包含了經(jīng)緯度
typedef struct {
CLLocationDegrees latitude;//緯度
CLLocationDegrees longitude;//經(jīng)度
} CLLocationCoordinate2D;
如果想創(chuàng)建一個(gè)CLLocationCoordinate2D我們一般使用如下的方法
CLLocationCoordinate2D CLLocationCoordinate2DMake(CLLocationDegrees latitude, CLLocationDegrees longitude)
- 定位獲取location信息的時(shí)候會(huì)執(zhí)行的協(xié)議方法
-(void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations{
if (locations && locations.count) {
CLLocationCoordinate2D lastLocation = locations.lastObject.coordinate;
NSLog(@"緯度%f 經(jīng)度%f",lastLocation.latitude,lastLocation.longitude);
}
}
- 定位出現(xiàn)錯(cuò)誤的時(shí)候
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(@"定位失敗-------%@",error.description);
}
地理編碼和反地理編碼
使用CLGeocoder可以完成地理編碼和反地理編碼
- 地理編碼:根據(jù)給定的地名,獲得具體的位置信息(比如經(jīng)緯度、地址的全稱等)
地理編碼的方法
-(void)geocodeAddressString:(NSString *)addressString completionHandler:
(CLGeocodeCompletionHandler)completionHandler;
- 反地理編碼:根據(jù)給定的經(jīng)緯度,獲得具體的位置信息。
反地理編碼的方法
-(void)reverseGeocodeLocation:(CLLocation *)location completionHandler:
(CLGeocodeCompletionHandler)completionHandler;
地理編碼
- 使用CLGeocoder類來創(chuàng)建一個(gè)實(shí)例對(duì)象
CLGeocoder *geo = [[CLGeocoder alloc]init];
- 使用創(chuàng)建好的實(shí)例對(duì)象來調(diào)用地理編碼的方法
CLPlacemark的字面意思是地標(biāo),它里面封裝了具體的位置信息,我們可以根據(jù)需要取出我們需要的信息。
[geo geocodeAddressString:@"這里寫地點(diǎn)名稱" completionHandler:^(NSArray<CLPlacemark *> * _Nullable
placemarks, NSError * _Nullable error) {
CLPlacemark *newPlacemarks = placemarks.lastObject;
NSLog(@"經(jīng)度 %f, 緯度 %f",
newPlacemarks.location.coordinate.latitude,newPlacemarks.location.coordinate.longitude);
NSLog(@"----+++++++++++++++++++++++%@",newPlacemarks.name);
}];
反地理編碼
- 使用CLGeocoder類來創(chuàng)建一個(gè)實(shí)例對(duì)象
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
- 使用創(chuàng)建好的實(shí)例對(duì)象來調(diào)用反地理編碼的方法
[geocoder reverseGeocodeLocation:@"這里填寫一個(gè)經(jīng)緯度" completionHandler:
^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
CLPlacemark *newPlacemark = placemarks.lastObject;
NSLog(@"%@",newPlacemark.country);
NSLog(@"%@",newPlacemark.addressDictionary);
NSLog(@"%@",[newPlacemark.addressDictionary objectForKey:@"City"]);
NSLog(@"%@",newPlacemark.name);
NSLog(@"%@",newPlacemark.location);
}];