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

[blockquote]

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

[/blockquote]

[blockquote]

本文相关目录: ================== 所属文集:【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 设备工具 ==================

[/blockquote]

定位目录:

官方框架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 {
&nbsp; &nbsp; if (!_locationM) {
&nbsp; &nbsp; &nbsp; &nbsp; // 创建CLLocationManager对象并设置代理
&nbsp; &nbsp; &nbsp; &nbsp; _locationM = [[CLLocationManager alloc] init];
&nbsp; &nbsp; &nbsp; &nbsp; _locationM.delegate = self;
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 请求前后台定位, 或前台定位授权, 并在Info.Plist文件中配置相应的Key
&nbsp; &nbsp; &nbsp; &nbsp; if ([_locationM respondsToSelector:@selector(requestAlwaysAuthorization)]) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [_locationM requestAlwaysAuthorization];
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp; &nbsp; return _locationM;
}

- (void)viewDidLoad {
&nbsp; &nbsp; [super viewDidLoad];
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; if([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]])
&nbsp; &nbsp; {
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; // 0.判断区域监听服务是否可用(定位服务是否关闭, 定位是否授权,是否开启飞行模式)
&nbsp; &nbsp; &nbsp; &nbsp; if ([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]]) {
&nbsp;&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 1.创建区域中心
&nbsp; &nbsp; &nbsp; &nbsp; CLLocationCoordinate2D center = CLLocationCoordinate2DMake(21.123, 124.345);
&nbsp; &nbsp; &nbsp; &nbsp; // 指定区域半径
&nbsp; &nbsp; &nbsp; &nbsp; CLLocationDistance radius = 100;
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 区域半径如果大于最大区域监听半径,则无法监听成功
&nbsp; &nbsp; &nbsp; &nbsp; if (radius > self.locationM.maximumRegionMonitoringDistance) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; radius = self.locationM.maximumRegionMonitoringDistance;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 根据区域中心和区域半径创建一个区域
&nbsp; &nbsp; &nbsp; &nbsp; CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; radius:radius
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; identifier:@"TD"];
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 2. 开始监听指定区域 (这个方法, 只会当进入或者离开区域这个动作触发时, 才会调用对应的代理方法)
&nbsp; &nbsp; &nbsp; &nbsp; [self.locationM startMonitoringForRegion:region];
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 请求获取某个区域的当前状态
&nbsp; &nbsp; &nbsp; &nbsp; [self.locationM requestStateForRegion:region];
&nbsp; &nbsp; } else {
&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"区域监听不可用");
&nbsp; &nbsp; }
&nbsp;}
}

#pragma mark - CLLocationManagerDelegate
#pragma mark - 进入监听区域后调用(调用一次)
- (void)locationManager:(nonnull CLLocationManager *)manager didEnterRegion:(nonnull CLRegion *)region {
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; NSLog(@"进入区域---%@", region.identifier);
}

#pragma mark - 进入监听区域后调用(调用一次)
- (void)locationManager:(nonnull CLLocationManager *)manager didExitRegion:(nonnull CLRegion *)region {
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; NSLog(@"离开区域---%@", region.identifier);
}

#pragma mark - 当监听区域失败时调用
// 监听区域个数是有上限的,如果大于上限,再注册区域就会失败,就会执行此方法)
- (void)locationManager:(nonnull CLLocationManager *)manager
monitoringDidFailForRegion:(nullable CLRegion *)region
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; withError:(nonnull NSError *)error {
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; // 经验: 一般都是在此处把比较远的区域给移除
//&nbsp; &nbsp; [manager stopMonitoringForRegion:region];
}

#pragma mark - 请求某个区域状态时, 回调的代理方法
- (void)locationManager:(CLLocationManager *)manager
&nbsp; &nbsp; &nbsp; didDetermineState:(CLRegionState)state
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; forRegion:(CLRegion *)region {
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; switch (state) {
&nbsp; &nbsp; &nbsp; &nbsp; case CLRegionStateUnknown:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"未知状态");
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; case CLRegionStateInside:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"在区域内部");
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; case CLRegionStateOutside:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"在区域外部");
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; default:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; }
}

- (void)didReceiveMemoryWarning {
&nbsp; &nbsp; [super didReceiveMemoryWarning];
&nbsp; &nbsp; // 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 {
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; @IBOutlet weak var Label: UILabel!
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; lazy var locationM: CLLocationManager = {
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; let locationM = CLLocationManager()
&nbsp; &nbsp; &nbsp; &nbsp; locationM.delegate = self
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 请求授权 配置key
&nbsp; &nbsp; &nbsp; &nbsp; if #available(iOS 8.0, *) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; locationM.requestAlwaysAuthorization()
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; return locationM
&nbsp; &nbsp; }()
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; override func viewDidLoad() {
&nbsp; &nbsp; &nbsp; &nbsp; super.viewDidLoad()
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 如果想要进行区域监听, 在ios8.0之后, 必须要请求用户的位置授权
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 0. 先判断区域监听是否可用
&nbsp; &nbsp; &nbsp; &nbsp; if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self){
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 1. 创建区域中心
&nbsp; &nbsp; &nbsp; &nbsp; let center = CLLocationCoordinate2DMake(21.123, 124.345)
&nbsp; &nbsp; &nbsp; &nbsp; var distance: CLLocationDistance = 10
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 区域半径如果大于最大区域监听半径,则无法监听成功
&nbsp; &nbsp; &nbsp; &nbsp; if distance > locationM.maximumRegionMonitoringDistance {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distance = locationM.maximumRegionMonitoringDistance
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 根据区域中心和区域半径创建一个区域
&nbsp; &nbsp; &nbsp; &nbsp; let region&nbsp; = CLCircularRegion(center: center, radius: distance, identifier: "TD")
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 2. 开始监听指定区域 (这个方法, 只会当进入或者离开区域这个动作触发时, 才会调用对应的代理方法)
&nbsp; &nbsp; &nbsp; &nbsp; locationM.startMonitoring(for: region)
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; // 请求获取某个区域的当前状态
&nbsp; &nbsp; &nbsp; &nbsp; locationM.requestState(for: region)
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; }else{
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("区域监听不可用")
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; override func didReceiveMemoryWarning() {
&nbsp; &nbsp; &nbsp; &nbsp; super.didReceiveMemoryWarning()
&nbsp; &nbsp; &nbsp; &nbsp; // Dispose of any resources that can be recreated.
&nbsp; &nbsp; }
}

extension ViewController: CLLocationManagerDelegate {
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; // 进入区域时调用
&nbsp; &nbsp; func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
&nbsp; &nbsp; &nbsp; &nbsp; print("进入区域--" + region.identifier)
&nbsp; &nbsp; &nbsp; &nbsp; Label.text = "进入区域"
&nbsp; &nbsp; }
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; // 离开区域时调用
&nbsp; &nbsp; func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
&nbsp; &nbsp; &nbsp; &nbsp; print("离开区域--" + region.identifier)
&nbsp; &nbsp; &nbsp; &nbsp; Label.text = "离开区域"
&nbsp; &nbsp; }
&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; // 当请求某个区域状态时, 如果获取到对应状态就会调用这个方法
&nbsp; &nbsp; func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; if region.identifier == "TD" {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if state == CLRegionState.inside{
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Label.text = "您已进入---" + region.identifier + "区域"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else if state == CLRegionState.outside {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Label.text = "您已离开---" + region.identifier + " 区域"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Label.text = "其他"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; } &nbsp; &nbsp;
}

打印结果:

进入区域--TD
离开区域--TD

[blockquote]

本文源码 Demo 详见 Github https://github.com/shorfng/iOS_7.0_Device-Tools

[/blockquote]

[blockquote]

作者:蓝田(Loto)

[/blockquote]

【作品发布平台】

① 简书 ② 安科开发 ③ Gitbook(如果觉得文章太长,请阅读此平台发布的文章)

【代码托管平台】

Github

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

评论区回复发送邮件[email protected]

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

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

支付宝扫一扫 向我打赏

你也可以微信 向我打赏

相关推荐