美文网首页
iOS自带定位功能实现

iOS自带定位功能实现

作者: 雨洒潇湘 | 来源:发表于2017-11-21 16:09 被阅读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)

    相关文章

      网友评论

          本文标题:iOS自带定位功能实现

          本文链接:https://www.haomeiwen.com/subject/yhjwvxtx.html