通过GPS数据反向地理信息编码, 得到当前位置信息

检查可用性

这属于基础知识, 不赘述, 总的来说,你的设备的支持要打开, 添加CoreLocation的framework, 引用头文件, 添加委托,然后, 好的实践是在使用前编程检查相关可用性:

- (CLLocationManager *)locationManager
{
    if(!_locationManager){
        if([CLLocationManager locationServicesEnabled]){
            _locationManager = [[CLLocationManager alloc] init];
            _locationManager.delegate = self;
            _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
            CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
            if (status == kCLAuthorizationStatusNotDetermined) {
                NSLog(@" not determined");
                if([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
                    [_locationManager requestAlwaysAuthorization];
                }
            }else if (status == kCLAuthorizationStatusDenied) {
                NSLog(@"denied");
            }else if (status == kCLAuthorizationStatusRestricted) {
                NSLog(@"restricted");
            }else if (status == kCLAuthorizationStatusAuthorizedAlways) {
                NSLog(@"always allowed");
            }else if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
                NSLog(@"when in use allowed");
            }else{
            }
        }else _locationManager = nil;
    }
    return _locationManager;
}

注意kCLAuthorizationStatusNotDetermined状态, iOS8以后, 需要手动编辑info.plist文件, 添加两个请求用户授权时的文案, 才能正常使用, 这里觉得匪夷所思:

<key>NSLocationWhenInUseUsageDescription</key>
<string>请授权使用地理位置服务</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>请授权使用地理位置服务</string>

以上, 可随便参考网上任何一篇教程

请求地理位置并反向编码

这里需要注意的是, 苹果的CLGeocoderAPI并不允许你频繁调用, 一分钟一次为宜, 所以你千万不要[self.locationManager startUpdatingLocation], 然后在locationManager:didChangeAuthorizationStatus:方法里去decode, 因为只是为了获取城市, 精度要求不高, 并且不需要持续更新, 所以我们就不update了, 只request一次, 然后在获取位置失败的时候再手动request一次:

+ (void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error{
    NSLog(@"fail with error:\n %@", error);
    [self.locationManager requestLocation];
}

相关解释参考这篇文章

语言的问题

因为习惯用英文系统, 就碰到请求回来的信息是英文的原因, 这里苹果是固化起来的, 暂时不支持用参数来指定返回数据的显示语言, 借鉴这篇文章的思路, 在请求前把当前语言设置保存起来, 临时改成中文, 请求结束后再修改回来:

+ (void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray *)locations{
    CLLocation *location = [locations lastObject];
    CLGeocoder *geocoder = [CLGeocoder new];
    // 修改语言为中文
    NSArray *currentLanguageArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];
    [[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:@"zh_Hans", nil] forKey:@"AppleLanguages"];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
        // 恢复语言
        [[NSUserDefaults standardUserDefaults] setObject:currentLanguageArray forKey:@"AppleLanguages"];
        if(error){
            NSLog(@"reverse error:%@", [error localizedDescription]);
        }else{
            if([placemarks count] > 0){
                CLPlacemark *mark = [placemarks firstObject];
                NSLog(@"%@", mark);
                NSLog(@"城市名:%@", mark.locality);
            }
        }
    }];
}
posted @ 2015-07-01 14:58  $walker  阅读(417)  评论(0编辑  收藏  举报