美文网首页
iOS学习笔记——LBS

iOS学习笔记——LBS

作者: oceanLong | 来源:发表于2018-02-16 01:59 被阅读45次

前言

在移动开发中,定位是非常重要的功能。移动端能够定位是有别于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。如有问题,欢迎指正。

相关文章

网友评论

      本文标题:iOS学习笔记——LBS

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