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 条评论
登录 后参与评论

相关文章

来自专栏向治洪

手把手教你从Core Data迁移到Realm

前言 Hybrid App(混合模式移动应用)是指介于web-app、native-app这两者之间的app,兼具“Native App良好用户交互体验的优势”...

2277
来自专栏编程之旅

iOS开发——Debug CUICatalog: Invalid asset name supplied: (null)

今天看到了一个Xcode log出了一个错误 CUICatalog:Invalid asset name supplied: (null), Google了一下...

923
来自专栏一“技”之长

iOS9系列专题五——全新的联系人与联系人UI框架

        在以前iOS开发中,涉及联系人相关的编程,代码都非常繁琐,并且框架的设计也不是Objective-C风格的,这使开发者用起来非常的难受。在iOS...

684
来自专栏iOS技术

透彻理解 NSNotificationCenter 通知

NSNotificationCenter这个东西作为iOS工程师想必都不陌生,但是有人可能连参数的意义都没搞明白,写这篇文章的目的不止是为了让不会用的人会用,更...

3477
来自专栏小樱的经验随笔

自己手动复现一个熊猫烧香病毒

最近逛了一下 bilibili ,偶然的一次机会,我在 bilibili 上看到了某个 up 主分享了一个他自己仿照熊猫病毒的原型制作的一个病毒的演示视频,虽然...

2342
来自专栏TechBox

GCD信号量-dispatch_semaphore_t

1971
来自专栏一“技”之长

我的女神——简洁实用的iOS代码调试框架 原

        这篇博客的起源是接手了公司的一个已经完成的项目,来做代码优化,项目工程很大,并且引入了很多公司内部的SDK,要搞清楚公司内部的这套框架,的确不是...

561
来自专栏算法+

谷歌开源项目Google Preview Image Extractor(PIEX) (附上完整demo代码)

前天偶然看到谷歌开源项目中有一个近乎无人问津的项目Google Preview Image Extractor(PIEX) 。 项目地址: https://gi...

5416
来自专栏有趣的django

一个完整的Django入门指南(三)

第五部分  Introduction Welcome to the 5th part of the tutorial series! In this tutor...

4487
来自专栏TechBox

iOS开发之ReactiveCocoa下的MVVM(干货分享)

1102

扫码关注云+社区