前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS学习笔记——LBS

iOS学习笔记——LBS

作者头像
Oceanlong
发布2018-07-03 13:23:27
1.7K0
发布2018-07-03 13:23:27
举报

前言

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

实践

CLLocationManager

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

LocationManager.h

代码语言:javascript
复制
#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

代码语言:javascript
复制
#import "LocationManager.h"

@implementation LocationManager

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

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

代码语言:javascript
复制
// LBS的精度选择,如设置10就只保证10米的精度。谨慎地选择精度,可以省电。
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// LBS的更新距离,如设置10表示,当位置改变超过10米时,会调用位置更新的回调。
_locationManager.distanceFilter = kCLDistanceFilterNone;
// LBS的回调代理,回调定位的更新or失败。
_locationManager.delegate = self;
代码语言:javascript
复制
#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中的代码是:

代码语言:javascript
复制
#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类:

代码语言:javascript
复制
#import "LocationManager.h"

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

代码语言:javascript
复制
var locationManager : LocationManager = LocationManager()


...
 locationManager.getLocation()

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.02.16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 实践
    • CLLocationManager
      • 权限
        • requestWhenInUseAuthorization vs requestAlwaysAuthorization
    • 补充学习点
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档