【iOS】7.4 定位服务->2.1.3.3 定位 - 官方框架CoreLocation 功能3:区域监听

本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正。

本文相关目录:

================== 所属文集:【iOS】07 设备工具 ==================

7.4 定位服务->1.0 简介

7.4 定位服务->2.1.1 定位 - 官方框架CoreLocation: 请求用户授权

7.4 定位服务->2.1.2 定位 - 官方框架CoreLocation: CLLocationManager位置管理器

7.4 定位服务->2.1.3.1 定位 - 官方框架CoreLocation 功能1:地理定位

7.4 定位服务->2.1.3.2 定位 - 官方框架CoreLocation 功能2:地理编码和反地理编码

7.4 定位服务->2.1.3.3 定位 - 官方框架CoreLocation 功能3:区域监听

7.4 定位服务->2.1.4 定位 - 官方框架CoreLocation 案例:指南针效果

7.4 定位服务->2.2 定位 - locationManager框架

7.4 定位服务->3.1 地图框架MapKit 功能1:地图展示

7.4 定位服务->3.2 地图框架MapKit 功能2:路线规划(导航)

7.4 定位服务->3.3 地图框架MapKit 功能3:3D视图

7.4 定位服务->3.4 地图框架MapKit 功能4:地图截图

7.4 定位服务->3.5 地图框架MapKit 功能5:POI检索

================== 所属文集:【iOS】07 设备工具 ==================

定位目录:

官方框架CoreLocation目录:

定位的功能实现:

本文目录:

1.0 概念解释

2.0 监听思路

3.0 问题:区域监听, 测试没有效果?

代码7:区域监听 Demo

编译环境:Xcode 8.0

模拟器版本:iOS 10

Swift版本:3.0

【OC 语言】

#import "ViewController.h"

#import <CoreLocation/CoreLocation.h>


@interface ViewController () <CLLocationManagerDelegate>

@property(nonatomic, strong) CLLocationManager *locationM;

@end


@implementation ViewController


#pragma mark - 懒加载

- (CLLocationManager *)locationM {

    if (!_locationM) {

        // 创建CLLocationManager对象并设置代理

        _locationM = [[CLLocationManager alloc] init];

        _locationM.delegate = self;

        

        // 请求前后台定位, 或前台定位授权, 并在Info.Plist文件中配置相应的Key

        if ([_locationM respondsToSelector:@selector(requestAlwaysAuthorization)]) {

            [_locationM requestAlwaysAuthorization];

        }

    }

    return _locationM;

}


- (void)viewDidLoad {

    [super viewDidLoad];

    

    if([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]])

    {

    

    // 0.判断区域监听服务是否可用(定位服务是否关闭, 定位是否授权,是否开启飞行模式)

        if ([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]]) {

      

        // 1.创建区域中心

        CLLocationCoordinate2D center = CLLocationCoordinate2DMake(21.123, 124.345);

        // 指定区域半径

        CLLocationDistance radius = 100;

        

        // 区域半径如果大于最大区域监听半径,则无法监听成功

        if (radius > self.locationM.maximumRegionMonitoringDistance) {

            radius = self.locationM.maximumRegionMonitoringDistance;

        }

        

        // 根据区域中心和区域半径创建一个区域

        CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center

                                                                     radius:radius

                                                                 identifier:@"TD"];

        

        // 2. 开始监听指定区域 (这个方法, 只会当进入或者离开区域这个动作触发时, 才会调用对应的代理方法)

        [self.locationM startMonitoringForRegion:region];

        

        // 请求获取某个区域的当前状态

        [self.locationM requestStateForRegion:region];

    } else {

        NSLog(@"区域监听不可用");

    }

 }

}


#pragma mark - CLLocationManagerDelegate

#pragma mark - 进入监听区域后调用(调用一次)

- (void)locationManager:(nonnull CLLocationManager *)manager didEnterRegion:(nonnull CLRegion *)region {

    

    NSLog(@"进入区域---%@", region.identifier);

}


#pragma mark - 进入监听区域后调用(调用一次)

- (void)locationManager:(nonnull CLLocationManager *)manager didExitRegion:(nonnull CLRegion *)region {

    

    NSLog(@"离开区域---%@", region.identifier);

}


#pragma mark - 当监听区域失败时调用

// 监听区域个数是有上限的,如果大于上限,再注册区域就会失败,就会执行此方法)

- (void)locationManager:(nonnull CLLocationManager *)manager

monitoringDidFailForRegion:(nullable CLRegion *)region

              withError:(nonnull NSError *)error {

    

    // 经验: 一般都是在此处把比较远的区域给移除

//    [manager stopMonitoringForRegion:region];

}


#pragma mark - 请求某个区域状态时, 回调的代理方法

- (void)locationManager:(CLLocationManager *)manager

      didDetermineState:(CLRegionState)state

              forRegion:(CLRegion *)region {

    

    switch (state) {

        case CLRegionStateUnknown:

            NSLog(@"未知状态");

            break;

        case CLRegionStateInside:

            NSLog(@"在区域内部");

            break;

        case CLRegionStateOutside:

            NSLog(@"在区域外部");

            break;

        default:

            break;

    }

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


@end

打印结果:

OC - 区域监听[12621:389819] 在区域内部


OC - 区域监听[12621:389819] 离开区域---TD

OC - 区域监听[12621:389819] 在区域外部


OC - 区域监听[12621:389819] 进入区域---TD

OC - 区域监听[12621:389819] 在区域内部

【Swift语言】

import UIKit

import CoreLocation


class ViewController: UIViewController {

    

    @IBOutlet weak var Label: UILabel!

    

    lazy var locationM: CLLocationManager = {

        

        let locationM = CLLocationManager()

        locationM.delegate = self

        

        // 请求授权 配置key

        if #available(iOS 8.0, *) {

            locationM.requestAlwaysAuthorization()

        }

        return locationM

    }()

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        // 如果想要进行区域监听, 在ios8.0之后, 必须要请求用户的位置授权

        

        // 0. 先判断区域监听是否可用

        if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self){

        

        // 1. 创建区域中心

        let center = CLLocationCoordinate2DMake(21.123, 124.345)

        var distance: CLLocationDistance = 10

        

        // 区域半径如果大于最大区域监听半径,则无法监听成功

        if distance > locationM.maximumRegionMonitoringDistance {

            distance = locationM.maximumRegionMonitoringDistance

        }

        

        // 根据区域中心和区域半径创建一个区域

        let region  = CLCircularRegion(center: center, radius: distance, identifier: "TD")

        

        // 2. 开始监听指定区域 (这个方法, 只会当进入或者离开区域这个动作触发时, 才会调用对应的代理方法)

        locationM.startMonitoring(for: region)

        

        // 请求获取某个区域的当前状态

        locationM.requestState(for: region)

        

        }else{

            print("区域监听不可用")

        }

    }

    

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

}


extension ViewController: CLLocationManagerDelegate {

    

    // 进入区域时调用

    func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {

        print("进入区域--" + region.identifier)

        Label.text = "进入区域"

    }

    

    // 离开区域时调用

    func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {

        print("离开区域--" + region.identifier)

        Label.text = "离开区域"

    }

    

    // 当请求某个区域状态时, 如果获取到对应状态就会调用这个方法

    func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {

        

        if region.identifier == "TD" {

            if state == CLRegionState.inside{

                Label.text = "您已进入---" + region.identifier + "区域"

            }else if state == CLRegionState.outside {

                Label.text = "您已离开---" + region.identifier + " 区域"

            }else {

                Label.text = "其他"

            }

        }

    }    

}

打印结果:

进入区域--TD

离开区域--TD


本文源码 Demo 详见 Github

https://github.com/shorfng/iOS_7.0_Device-Tools

作者:蓝田(Loto)

【作品发布平台】

① 简书

② 博客园

③ Gitbook(如果觉得文章太长,请阅读此平台发布的文章)

【代码托管平台】

Github

【如有疑问,请通过以下方式交流】

① 评论区回复

② 发送邮件至 shorfng@126.com


本文版权归作者和本网站共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

支付宝扫一扫 向我打赏

你也可以微信 向我打赏详细资料,请加群获取:586656942

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值