iOS自带定位功能实现

2017-11-21  本文已影响555人  雨洒潇湘

定位功能介绍

关于定位开发一般用两种方法实现,一种使用高德百度的第三方SDK,另一种使用苹果自带的CoreLocation框架。我介绍的也只是CoreLocation框架,关于第三方的SDK介绍,大家可以参考他们提供的文档。定位时候主要使用CLLocationManager、 CLLocationManagerDelegate和CLLocation。CLLocationManager是定位服务管理类它能够给我们提供获得 设备的位置信息和高度信息,也可以监控设备进入或离开某个区域,它还可以帮助获得设备的运行方向等。CLLocationManagerDelegate 是CLLocationManager类委托协议。CLLocation类是封装了位置和高度信息。

方法实现

权限申请

在项目的 Info.plist 添加定位权限申请,其中:
iOS 8 - iOS 10 版本:
NSLocationWhenInUseUsageDescription 表示应用在前台的时候可以搜到更新的位置信息。
NSLocationAlwaysUsageDescription 申请Always权限,以便应用在前台和后台(suspend 或 terminated)都可以获取到更新的位置数据。
iOS 11 版本:
NSLocationAlwaysAndWhenInUseUsageDescription 申请Always权限,以便应用在前台和后台(suspend 或 terminated)都可以获取到更新的位置数据(NSLocationWhenInUseUsageDescription 也必须有)。
注意:如果需要同时支持在iOS8-iOS10和iOS11系统上后台定位,建议在plist文件中同时添加NSLocationWhenInUseUsageDescription、NSLocationAlwaysUsageDescription和NSLocationAlwaysAndWhenInUseUsageDescription权限申请。
在App Transport Security Settings下添加Allow Arbitrary Loads设置成Bool类型,设为YES。

代码实现

#import <CoreLocation/CoreLocation.h>//引入Corelocation框架
@interface LocationViewController ()< CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;//设置manager
@property (nonatomic, strong) NSString *currentCity;
@end

@implementation LocationViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self locate];
}

- (void)locate {
    if ([CLLocationManager locationServicesEnabled]) {//监测权限设置
        self.locationManager = [[CLLocationManager alloc]init];
        self.locationManager.delegate = self;//设置代理
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//设置精度
        self.locationManager.distanceFilter = 1000.0f;//距离过滤
        [self.locationManager requestAlwaysAuthorization];//位置权限申请
        [self.locationManager startUpdatingLocation];//开始定位
    }
}
#pragma mark location代理
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"您还未开启定位服务,是否需要开启?" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    }];
    UIAlertAction *queren = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSURL *setingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication]openURL:setingsURL];
    }];
    [alert addAction:cancel];
    [alert addAction:queren];
    [self.navigationController presentViewController:alert animated:YES completion:nil];
}

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    [self.locationManager stopUpdatingLocation];//停止定位
//地理反编码
    CLLocation *currentLocation = [locations lastObject];
    CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
//当系统设置为其他语言时,可利用此方法获得中文地理名称
    NSMutableArray
    *userDefaultLanguages = [[NSUserDefaults standardUserDefaults]objectForKey:@"AppleLanguages"];
    // 强制 成 简体中文
    [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"zh-hans", nil]forKey:@"AppleLanguages"];
    [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (placemarks.count > 0) {
            CLPlacemark *placeMark = placemarks[0];
            NSString *city = placeMark.locality;
            if (!city) {
                self.currentCity = @"⟳定位获取失败,点击重试";
            } else {
                self.currentCity = placeMark.locality ;//获取当前城市
             
            }

        } else if (error == nil && placemarks.count == 0 ) {
        } else if (error) {
            self.currentCity = @"⟳定位获取失败,点击重试";
        }
        // 还原Device 的语言
        [[NSUserDefaults
          standardUserDefaults] setObject:userDefaultLanguages
         forKey:@"AppleLanguages"];
    }];
}

CLPlacemark属性详解

947539-20160818142431609-2143381124.jpeg

其中四个直辖市中的administrativeArea(省)为nil,可根据此判断直辖市。

参考文章

(http://mobile.51cto.com/hot-445901.htm)

上一篇下一篇

猜你喜欢

热点阅读