美文网首页iOS技术分享程序员iOS开发
iOS开发-iOS原生定位简单封装

iOS开发-iOS原生定位简单封装

作者: it_hao528 | 来源:发表于2016-09-30 16:28 被阅读1341次

    相信各位做开发的程序猿们在开发中使用到定位功能的项目应该挺多的,iOS原生的定位非常简单且快速,为了在使用过程中让大家觉得更加的简单方便一些,小编对iOS原声的定位做了进一步的简单封装,具体代码如下:
    1、创建存储地理位置的模型,导入<CoreLocation/CoreLocation.h>(方便存储经纬度)

    #import <Foundation/Foundation.h>
    #import <CoreLocation/CoreLocation.h>
    
    @interface Location : NSObject
    
    //国家
    @property (nonatomic, copy) NSString * country;
    //省 直辖市
    @property (nonatomic, copy) NSString * administrativeArea;
    // 地级市 直辖市区
    @property (nonatomic, copy) NSString * locality;
    //县 区
    @property (nonatomic, copy) NSString * subLocality;
    //街道
    @property (nonatomic, copy) NSString * thoroughfare;
    //子街道
    @property (nonatomic, copy) NSString * subThoroughfare;
    
    //经度
    @property (nonatomic, assign) CLLocationDegrees longitude;
    //纬度
    @property (nonatomic, assign) CLLocationDegrees latitude;
    
    @end
    

    大家使用的时候可以将以上属性命名为自己容易记的名字。

    2、创建定位类,导入模型头文件,并设置协议及代理方法

    #import <Foundation/Foundation.h>
    #import "Location.h"
    
    @protocol RHLocationDelegate;
    
    @interface RHLocation : NSObject
    
    @property (nonatomic, weak) id<RHLocationDelegate> delegate;
    
    - (void)beginUpdatingLocation;
    @end
    @protocol RHLocationDelegate <NSObject>
    
    - (void)locationDidEndUpdatingLocation:(Location *)location;
    @end
    

    3、在.m文件中创建定位CLLocationManager的对象,并遵守代理协议。使用时只需要遵循本类的协议代理,调用beginUpdatingLocation方法即可。在代理回调里边可以通过存储位置信息的模型类获取到想要的位置信息。

    #import "RHLocation.h"
    
    @interface RHLocation () <CLLocationManagerDelegate>
    
    @property (nonatomic, strong) CLLocationManager * locationManager;
    @end
    
    @implementation RHLocation
    
    #pragma mark - public
    - (void)beginUpdatingLocation {
        
        [self.locationManager startUpdatingLocation];
    }
    
    #pragma mark - location delegate
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
        
        //获取新的位置
        CLLocation * newLocation = locations.lastObject;
        
        //创建自定制位置对象
        Location * location = [[Location alloc] init];
    
        //存储经度
        location.longitude = newLocation.coordinate.longitude;
        
        //存储纬度
        location.latitude = newLocation.coordinate.latitude;
        
        //根据经纬度反向地理编译出地址信息
        CLGeocoder * geocoder = [[CLGeocoder alloc] init];
        
       [geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
            
            if (placemarks.count > 0) {
                
                CLPlacemark * placemark = placemarks.firstObject;
                
                //存储位置信息
                location.country = placemark.country;
                location.administrativeArea = placemark.administrativeArea;
                location.locality = placemark.locality;
                location.subLocality = placemark.subLocality;
                location.thoroughfare = placemark.thoroughfare;
                location.subThoroughfare = placemark.subThoroughfare;
            }
        }];
    
        //设置代理方法
        if ([self.delegate respondsToSelector:@selector(locationDidEndUpdatingLocation:)]) {
            
            [self.delegate locationDidEndUpdatingLocation:location];
        }
        //系统会一直更新数据,直到选择停止更新,因为我们只需要获得一次经纬度即可,所以获取之后就停止更新
        [manager stopUpdatingLocation];
    }
    
    #pragma mark - setter and getter
    - (CLLocationManager *)locationManager {
        
        if (!_locationManager) {
            
            _locationManager = [[CLLocationManager alloc] init];
            
            _locationManager.delegate = self;
            
            // 设置定位精确度
            _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
            
            // 设置过滤器为无
            _locationManager.distanceFilter = kCLDistanceFilterNone;
            
            // 取得定位权限,有两个方法,取决于你的定位使用情况
            // 一个是 requestAlwaysAuthorization
            // 一个是 requestWhenInUseAuthorization
            [_locationManager requestAlwaysAuthorization];//ios8以上版本使用。
        }
        return _locationManager;
    }
    @end
    

    截止到这里,我们就算是封装完成,在使用的时候只需要导入RHLocation的头文件即可,遵循代理协议即可。

    4、使用:Xcode8.0在使用之前需要在plist里边添加两个字段Privacy - Location Always Usage Description和Privacy - Location When In Use Usage Description,否则会出错。如果是Xcode8.0以下版本同样需要添加Location Always Usage Description和Location When In Use Usage Description两个字段。

    #import "ViewController.h"
    //导入头文件
    #import "RHLocation.h"
    
    @interface ViewController () <RHLocationDelegate>
    //设置成属性
    @property (nonatomic, strong) RHLocation * location;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        //开始更新定位
        [self.location beginUpdatingLocation];
    }
    
    #pragma mark - RHLocation delegate
    - (void)locationDidEndUpdatingLocation:(Location *)location {
        
        //在此对需要的数据进行处理使用
        NSLog(@"国家:%@",location.country);
        NSLog(@"省/直辖市:%@",location.administrativeArea);
        NSLog(@"地级市/直辖市区:%@",location.locality);
        NSLog(@"县/区:%@",location.subLocality);
        NSLog(@"街道:%@",location.thoroughfare);
        NSLog(@"子街道:%@",location.subThoroughfare);
        
        NSLog(@"经度:%lf",location.longitude);
        NSLog(@"纬度:%lf",location.latitude);
    }
    
    //懒加载创建自定制的位置类对象
    - (RHLocation *)location {
        
        if (!_location) {
            
            _location = [[RHLocation alloc] init];
            
            _location.delegate = self;
        }
        return _location;
    }
    

    OK!到此结束,代码已经说得很详细了,就不传demo了。

    最后还是希望能够帮助到有需要的程序猿们,同时希望大家能够多多提意见,愿同是程序猿的我们在开发的道路上共同成长。谢谢!!!

    相关文章

      网友评论

      • 被风吹乱的思念:您好,我的定位不走代理是为么?
        it_hao528:@被风吹傻的娇娇 检查代理是否设置,定位权限是否开启,开启定位方法是否调用
      • 这小子:总感觉你的#import "RHLocation.h"的代理方法走早了,获取省市区等字段前就已经走了代理方法
      • it_hao528:刚无意中发现代码中少设置了代理方法, 已经添加上, 如果给小伙伴带来了不便, 还望大家见谅!
        it_hao528:@这小子1992 嗯 你说的有道理 应该是对model赋值之后再启动代理 多谢指出
        这小子:@Abner_G 你应该在获取到省市区街道之后再启动代理方法,把代理方法放在if里面才可以
        这小子:@Abner_G 你上面的代码缺少什么代理?我测试调不出省市区,只能调出经纬度,怎么回事?

      本文标题:iOS开发-iOS原生定位简单封装

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