iOS学习笔记——LBS

前言

在移动开发中,定位是非常重要的功能。移动端能够定位是有别于PC的最大原因。

实践

CLLocationManager

iOS为我们提供了位置服务类CLLocationManager

LocationManager.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@interface LocationManager : NSObject<CLLocationManagerDelegate>

@property (strong,strong ) CLLocationManager *locationManager;//定位服务
@property (nonatomic,copy)    NSString *currentCity;//城市
@property (nonatomic,copy)    NSString *strLatitude;//经度
@property (nonatomic,copy)    NSString *strLongitude;//维度

- (void)getLocation;
@end

LocationManager.m

#import "LocationManager.h"

@implementation LocationManager

CLLocationManager *_locationManager;//定位服务
 NSString *_currentCity;//城市
NSString *_strLatitude;//经度
NSString *_strLongitude;//维度

同时,CLLocationManager给我们提供了一些关于LBS的配置:

// LBS的精度选择,如设置10就只保证10米的精度。谨慎地选择精度,可以省电。
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// LBS的更新距离,如设置10表示,当位置改变超过10米时,会调用位置更新的回调。
_locationManager.distanceFilter = kCLDistanceFilterNone;
// LBS的回调代理,回调定位的更新or失败。
_locationManager.delegate = self;
#pragma mark - 定位失败
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    printf("定位失败\n");
}

#pragma mark - 定位成功
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    printf("定位成功");
}

权限

定位功能在iOS系统中是一个需要权限的功能。我们在Info.plist文件中,添加定位权限和相关的权限描述。这样当我们需要使用时,系统就会弹窗,用我们的权限描述来问用户,是否需要打开定位权限。

Info.plist

在Info.plist中完成描述后,我们在调用获取位置的方法时,也要先申请权限。

requestWhenInUseAuthorization vs requestAlwaysAuthorization

这两个权限简单来说,一个是需要App在前台才能够使用定位的功能,另一个是在后台也可以使用定位的功能。

具体的情况和trick点,苹果官方都有比较详细的说明,不再赘述。

requestWhenInUseAuthorization

requestAlwaysAuthorization

最终,我们在LocationManager.m中的代码是:

#import "LocationManager.h"

@implementation LocationManager

CLLocationManager *_locationManager;//定位服务
 NSString *_currentCity;//城市
NSString *_strLatitude;//经度
NSString *_strLongitude;//维度
 

- (void)getLocation{
 
    printf("OC get location\n");
        if ([CLLocationManager locationServicesEnabled]) {
            
            _currentCity = [[NSString alloc]init];
            if (_locationManager == NULL) {
                _locationManager = [[CLLocationManager alloc]init];
                _locationManager.delegate = self;
                [_locationManager requestWhenInUseAuthorization];
                _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
                _locationManager.distanceFilter = kCLDistanceFilterNone;
                [_locationManager startMonitoringSignificantLocationChanges];
                
            }
            printf("start update location\n");
            [_locationManager startUpdatingLocation];
        
        }
    
}

#pragma mark - 定位失败
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    printf("定位失败\n");
    printf("%s", error.code);
}

#pragma mark - 定位成功
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    printf("定位成功");
    [_locationManager stopUpdatingLocation];
    CLLocation *currentLocation = [locations lastObject];
    CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
    //当前的经纬度
    NSLog(@"当前的经纬度 %f,%f",currentLocation.coordinate.latitude,currentLocation.coordinate.longitude);
    //这里的代码是为了判断didUpdateLocations调用了几次 有可能会出现多次调用 为了避免不必要的麻烦 在这里加个if判断 如果大于1.0就return
    NSTimeInterval locationAge = -[currentLocation.timestamp timeIntervalSinceNow];
    if (locationAge > 1.0){//如果调用已经一次,不再执行
        return;
    }
    //地理反编码 可以根据坐标(经纬度)确定位置信息(街道 门牌等)
    [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (placemarks.count >0) {
            CLPlacemark *placeMark = placemarks[0];
            _currentCity = placeMark.locality;
            if (!_currentCity) {
                _currentCity = @"无法定位当前城市";
            }
            //看需求定义一个全局变量来接收赋值
            NSLog(@"当前国家 - %@",placeMark.country);//当前国家
            NSLog(@"当前城市 - %@",_currentCity);//当前城市
            NSLog(@"当前位置 - %@",placeMark.subLocality);//当前位置
            NSLog(@"当前街道 - %@",placeMark.thoroughfare);//当前街道
            NSLog(@"具体地址 - %@",placeMark.name);//具体地址
            NSString *message = [NSString stringWithFormat:@"%@,%@,%@,%@,%@",placeMark.country,_currentCity,placeMark.subLocality,placeMark.thoroughfare,placeMark.name];        
        }else if (error == nil && placemarks.count){
            
            NSLog(@"NO location and error return");
        }else if (error){
            
            NSLog(@"loction error:%@",error);
        }
    }];
    
}


@end

补充学习点

由于我外部的代码,使用了Swift,在写完LocationManager后,就涉及到Swift调用OC类的问题。

苹果给出的方法是:会新建一个文件叫<ProjectName>-Bridging-Header.h 我们在其中添加,OC类:

#import "LocationManager.h"

然后就可以直接在Swift中调用了

var locationManager : LocationManager = LocationManager()


...
 locationManager.getLocation()

以上,初学iOS。如有问题,欢迎指正。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨熹的专栏

Python 爬虫 2 爬取多页网页

参考资料:极客学院: Python单线程爬虫 代码:2.Single-thread-crawler.ipynb 本文内容: Requests.get 爬取多个页...

3425
来自专栏斑斓

代码诊所

几年前,我有机会负责一个项目的咨询。团队很小,目标是对旧有系统的后端用Java改写,而团队的开发人员全为C程序员。我的工作职责是负责项目设计、开发,以及担任项目...

3306
来自专栏mwangblog

git,版本控制界的魔术师(1/18/2018)

892
来自专栏Kirito的技术分享

中文文案排版指南

目录 空格 中英文之间需要增加空格 中文与数字之间需要增加空格 数字与单位之间需要增加空格 全角标点与其他字符之间不加空格 -ms-text-autospac...

4048
来自专栏Java架构

想进阿里、京东、美团面试的Java程序员看过来第一个问题:阿里面试问些什么

2066
来自专栏一“技”之长

iOS开发中活动视图控制器UIActivityViewController的应用

    在iOS开发中,UIActivityViewController常用来弹出分享面板,其实除了用来社会化分享,UIActivityViewControll...

921
来自专栏华仔的技术笔记

要你命三千:老代码中的那些坑 define STRHASSBUSTR(str,subStr) ...

3035
来自专栏木子昭的博客

Javascript是个好东西(广大人民的智慧是无穷的):

图片发自简书App 1,面向对象? 其他编程语言对于面向对象要么支持,要么不支持,而js支持原型链,具体的实现要自己动手,实现的方式也是各种流派(相当于别人家的...

2648
来自专栏FreeBuf

XSS挑战第一期Writeup

0×00起因 这期XSS挑战的起因是在阅读“Modern Web Application Firewalls Fingerprinting and By...

19710
来自专栏java一日一条

不愿看到Java开发者再做的10件事

编者注:Andy是OSI(开发系统集成者)的CEO,同时也是位思想先锋及优秀博客作者。

382

扫码关注云+社区