地图定位获取当前经纬度, 及各种位置信息

需要在Info.plist文件中设置一下,加入一个NSLocationWhenInUseUsageDescription(前台获取GPS定位),NSLocationAlwaysUsageDescription(前后台获取GPS定位),Value可以为空;

引头文件
#import
签协议

@interface ViewController ()

写俩懒加载, 待会会用到

- (CLGeocoder *)geocoder{

    if (!_geocoder) {
        _geocoder = [[CLGeocoder alloc] init];
    }
    return _geocoder;
}

- (CLLocationManager *)locationManager{

    if (!_locationManager) {
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.delegate = self;
        _locationManager.desiredAccuracy =       kCLLocationAccuracyBest;
    }
    return _locationManager;
}

接下来可以在 viewDidLoad 和 刷新定位按钮响应事件 的地方调用下面方法, 开始定位, 最好别在viewWillAppear调用, 用户关闭过一次权限她不想老被提醒
#pragma mark - 定位
- (void)beginLocate{

    if ([CLLocationManager locationServicesEnabled]) {
        /** 由于IOS8中定位的授权机制改变 需要进行手动授权
         * 获取授权认证,两个方法:
         * [self.locationManager requestWhenInUseAuthorization];
         * [self.locationManager requestAlwaysAuthorization];
         */
        if ([self.locationManager   respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
//                NSLog(@"requestWhenInUseAuthorization");
            [self.locationManager requestWhenInUseAuthorization];
        }
    
        //开启定位, 不断调用其代理方法
        [self.locationManager startUpdatingLocation];
//        NSLog(@"start gps");
    }
    if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
        NSLog(@"定位权限被关闭");
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"抱歉" message:@"您尚未开启定位权限" preferredStyle:UIAlertControllerStyleAlert];
    
        UIAlertAction *actionCancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:nil];
    
        UIAlertAction *actionOk = [UIAlertAction actionWithTitle:@"去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
       
            [self jumpToSetting];
        
        }];
    
        [alertController addAction:actionCancel];
        [alertController addAction:actionOk];
        [self presentViewController:alertController animated:YES completion:nil];
    
    }

}

#pragma mark - 去系统设置开启权限
- (void)jumpToSetting{

    NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];

    //info plist中URL type中添加一个URL Schemes添加一个prefs值
    if([[UIApplication sharedApplication] canOpenURL:url]){
        //跳转到定位
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=LOCATION_SERVICES"]];
    }

}

这是定位的代理方法
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{

if(!_isLocationed){
    //1.获取最新的一次位置信息
    CLLocation *location = [locations lastObject];
    CLLocationCoordinate2D coordinate = location.coordinate;
    //NSLog(@"经度:%f, 纬度:%f", coordinate.longitude, coordinate.latitude);
    //逆地理编码得到当前定位城市
    [self reGeoCoderLocation:coordinate];
    }else{
    //2.停止定位
    [self.locationManager stopUpdatingLocation];
    }
    }
  #pragma mark - 逆地理编码
   - (void)reGeoCoderLocation:(CLLocationCoordinate2D)coordinate{

    //根据经纬度反向地理编译出地址信息
    CLLocation *location = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
    [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {
    
        if (placemarks.count > 0) {
            CLPlacemark *placemark = placemarks.firstObject;
        
            //placemark.name位置全名
            //
            //placemark.thoroughfare街道
            //
            //placemark.subThoroughfare子街道
            //
            // placemark.locality市
            //
            //placemark.subLocality区
            //
            //placemark.country国家
        
            //NSLog(@"全称:%@, 市:%@, 区:%@, 街道:%@, 子街道:%@", placemark.name, placemark.locality, placemark.subLocality, placemark.thoroughfare, placemark.subThoroughfare);

          //NSString *city = placemark.locality;
        if (!city) {
            //四大直辖市的城市信息无法通过locality获得,只能通过获取省份的方法来获得(如果city为空,则可知为直辖市)
            city = placemark.administrativeArea;
        }

            //获取具体位置
            NSString *strOfAccurate = placemark.name;
            NSString *strOfCity = placemark.locality;
            NSString *strOfThroughfare = placemark.thoroughfare;
            if (!strOfCity || !strOfAccurate || !strOfThroughfare) {
                _isLocationed = NO;
                [self.locationManager startUpdatingLocation];
            }else{
                _isLocationed = YES;
            
                _locationView.labelOfLocation.text = [NSString stringWithFormat:@"当前: %@%@", strOfCity, strOfAccurate];
            }
        
        }
    
    else if (error == nil && placemarks.count == 0){
        NSLog(@"定位无返回结果");
    }
    else if(error != nil){
        NSLog(@"location error: %@", error);
    }
    
    }];

    }

#pragma mark - 试图将要消失
- (void)viewWillDisappear:(BOOL)animated{

    [super viewWillDisappear:animated];
    //定位停止
    [self.locationManager stopUpdatingLocation];
}

以下这个协议方法也可以
//代理方法:获取地理位置变化的起始点和终点,didUpdateToLocation:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
//将经度显示到label上
self.longitude.text = [NSString stringWithFormat:@"%lf", newLocation.coordinate.longitude];
//将纬度显示到label上
self.latitude.text = [NSString stringWithFormat:@"%lf", newLocation.coordinate.latitude];

    // 获取当前所在的城市名
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];

    //根据经纬度反向地理编译出地址信息
    [geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *array, NSError *error){
    
        if (array.count > 0){
        
            CLPlacemark *placemark = [array objectAtIndex:0];
            //将获得的所有信息显示到label上
            self.location.text = placemark.name;
            //获取城市
            NSString *city = placemark.locality;
            if (!city) {
                //四大直辖市的城市信息无法通过locality获得,只能通过获取省份的方法来获得(如果city为空,则可知为直辖市)
                city = placemark.administrativeArea;
            }
                NSLog(@"city = %@", city);
            _cityLable.text = city;
//              [_cityButton setTitle:city forState:UIControlStateNormal];
        }
        else if (error == nil && [array count] == 0)
        {
            NSLog(@"No results were returned.");
        }
        else if (error != nil)
        {
            NSLog(@"An error occurred = %@", error);
        }
    }];
    //系统会一直更新数据,直到选择停止更新,因为我们只需要获得一次经纬度即可,所以获取之后就停止更新
    [manager stopUpdatingLocation];
}

你可能感兴趣的:(地图定位获取当前经纬度, 及各种位置信息)