定位

一、定位属于用户的隐私,iOS8.0之后获取定位需向用户进行授权

授权方式:

    1.1、前台授权,info.plist文件里设置字典“NSLocationWhenInUseUsageDescription

        注意:若前台授权的状态下,想获取后台定位,需勾选后台模式,如图






 1.2、前后台授权,

在info.plist文件中配置字典NSLocationAlwaysUsageDescription,

如图:


1.3、若在info.plist中前后台授权和前台授权都有配置,则用请求权限比较高的那个,即前后台授权

1.4、授权之后、设置代理,完成相应的代理方法即可

二、相关的代码

2.1、OC代码:

调用:

#import "ViewController.h"
#import "SHLocationTool.h"
@implementation ViewController
- (IBAction)clickBtn:(id)sender {
    
    [[SHLocationTool shareInstance]getCurrentLocationWithOnce:NO andResultBlock:^(CLLocation *location, NSString *errorMsg) {
        if (!errorMsg) {
            NSLog(@"latitude,%lf longitude,%lf errorMsg,%@",location.coordinate.latitude,location.coordinate.longitude,errorMsg);
        }else {
            NSLog(@"latitude,%lf longitude,%lf errorMsg,%@",location.coordinate.latitude,location.coordinate.longitude,errorMsg);
        }
        
    }];
}

代码实现:
//
//  SHLocationTool.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
typedef void(^ResultBlock)(CLLocation *location,NSString *errorMsg);
@interface SHLocationTool : NSObject
+ (instancetype)shareInstance;
- (void)getCurrentLocationWithOnce:(BOOL)isOnce andResultBlock:(ResultBlock)resultBlock;



@end
#import "SHLocationTool.h"
#import <UIKit/UIKit.h>
#define kSystemVersion [UIDevice currentDevice].systemVersion
#define kIsVersion8         [kSystemVersion floatValue] >= 8.0
#define kIsVersion9         [kSystemVersion floatValue] >= 9.0
@interface SHLocationTool ()<CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *locationM;//位置管理者
@property (nonatomic, copy) ResultBlock resultBlock;//结果block
@property (nonatomic, assign) BOOL isOnce;//是获取一次还是始终获取
@end
@implementation SHLocationTool
static SHLocationTool *_locationTool;
+ (instancetype)shareInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _locationTool = [[SHLocationTool alloc]init];
    });
    return _locationTool;
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    CLLocation *loc = locations.lastObject;
    if (!loc && self.resultBlock) {
        self.resultBlock(nil,@"没有获取到位置信息");
        return;
    }
    self.resultBlock(loc,nil);
    if (self.isOnce) {
        [manager stopUpdatingLocation];
    }
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
        case kCLAuthorizationStatusDenied:
            self.resultBlock(nil,@"当前被拒绝");
            break;
        case kCLAuthorizationStatusRestricted:
            self.resultBlock(nil,@"当前受限制");
            break;
        case kCLAuthorizationStatusNotDetermined:
            self.resultBlock(nil,@"用户没决定哈哈哈哈哈哈");
            break;
        default:
            break;
    }
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    [manager startUpdatingLocation];
}
#pragma mark - Public Methods
- (void)getCurrentLocationWithOnce:(BOOL)isOnce andResultBlock:(ResultBlock)resultBlock
{
    self.resultBlock = resultBlock;
    self.isOnce = isOnce;
    if ([CLLocationManager locationServicesEnabled]) {
        [self.locationM startUpdatingLocation];
    }else {
        if (self.resultBlock) {
            self.resultBlock(nil,@"没有开启定位服务");
        }
    }
}
#pragma mark - Getters
- (CLLocationManager *)locationM
{
    if (!_locationM) {
        _locationM = [[CLLocationManager alloc]init];
        _locationM.delegate = self;
        // 强求授权
        // 版本判断
        if (kIsVersion8) {
            //请求前后台定位授权
            //请求前台定位授权
            //1、获取info.plist文件的内容
            NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
            if (!infoDic) {
                return _locationM;
            }
            //2、获取前台定位授权的key 值
            NSString *whenInUse = infoDic[@"NSLocationWhenInUseUsageDescription"];
            
            //3、获取前后台定位授权的key 值
            NSString *always = infoDic[@"NSLocationAlwaysUsageDescription"];
            
            //4、如果两个都有,用请求权限比较高的那个
            if (always != nil) {
                [_locationM requestAlwaysAuthorization];
            }else if (whenInUse != nil) {
                [_locationM requestWhenInUseAuthorization];
                //1、判断后台模式有没有勾选location updates
                //2、判断当前版本是否是iOS9.0,只有在iOS9.0之后才需要额外设置一个属性为ture
                NSArray *backModes = infoDic[@"UIBackgroundModes"];
                NSLog(@"%@",kSystemVersion);
                if (backModes != nil && [backModes containsObject:@"location"] && kIsVersion9) {
                    _locationM.allowsBackgroundLocationUpdates = YES;
                }
            }else {
                NSLog(@"请在info.plist进行相关的配置");
            }
        }
    }
    return _locationM;
}
@end

2.2、Swift代码:

调用:

import UIKit
class ViewController: UIViewController {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        SHLocationTool.shareInstance.getCurrentLocation(isOnce: false) { (loc, errorMsg) -> () in
            if errorMsg == nil {
                print(loc)
            }
        }
        
    }
}

代码实现:
import UIKit
import Foundation
import CoreLocation
typealias LocationResultBlock = (_:CLLocation?,_:String?) -> ()
class SHLocationTool: NSObject {
    var isOnce:Bool = false
    static let shareInstance = SHLocationTool()
    
    lazy var locationM: CLLocationManager = {
        // 创建定位管理者
        let locationM = CLLocationManager()
        // 设置代理
        locationM.delegate = self
        
        if #available(iOS 8.0, *) {
            /*
             1、取info.plist中的键值对
             2、查看有没有设置键:
                2.1、NSLocationAlwaysUsageDescription,用于前后台授权
                2.2、NSLocationWhenInUseUsageDescription,用于前台授权
                    注意:iOS9.0之后需设置allowsBackgroundLocationUpdates属性值为ture,才具有后台授权的功能
             */
            // 1. 获取info.plist文件内容
            guard let infoDic = Bundle.main.infoDictionary else {return locationM}
            // 2. 获取前台定位授权的key 值
            let whenInUse = infoDic["NSLocationWhenInUseUsageDescription"]
            // 3. 获取前后台定位授权key 值
            let always = infoDic["NSLocationAlwaysUsageDescription"]
            
            // 4. 判断: 如果两个都有, 请求权限比较高的哪一个
            //  如果只有某一个, 那就请求对应的授权
            //  如果两个都没有, 给其他开发者提醒
            
            if always != nil {
                locationM.requestAlwaysAuthorization()
            }else if whenInUse != nil {
                locationM.requestWhenInUseAuthorization()
                
                // 1. 判断后台模式有没有勾选location updates
                // 2. 判断当前版本时候是ios9.0, 因为只有在ios9.0以后, 才需要额外的设置一个属性为true
                let backModes = infoDic["UIBackgroundModes"]
                if backModes != nil {
                    let resultBackModel = backModes as! [String]
                    if resultBackModel.contains("location") {
                        if #available(iOS 9.0, *) {
                            locationM.allowsBackgroundLocationUpdates = true
                        }
                    }
                    
                }
            }else {
                print("在info.plist中配置")
            }
            
        }
        return locationM
    }()
   
    var resultBlock: LocationResultBlock?
    
    func getCurrentLocation(isOnce:Bool, resultBlock: @escaping LocationResultBlock) -> () {
        self.isOnce = isOnce
        self.resultBlock = resultBlock
        
        if CLLocationManager.locationServicesEnabled() {
            locationM.startUpdatingLocation()
        }else {
            if self.resultBlock != nil {
                self.resultBlock!(nil,"当前没有开启定位服务")
            }
        }
    }
    
    
}
extension SHLocationTool:CLLocationManagerDelegate {
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard locations.last != nil else {
            if resultBlock != nil {
                resultBlock!(nil, "没有获取到用户位置信息")
            }
            return
        }
        resultBlock!(locations.last,nil)
        if isOnce {
            manager.stopUpdatingLocation()
        }
        
    }
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        
        switch status {
        case .denied:
            resultBlock!(nil,"当前被拒绝")
        case .restricted:
            resultBlock!(nil,"当前受限制")
        case .notDetermined:
            resultBlock!(nil,"用户没决定")
        default:
            print("nono")
        }
        
    }
  
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值