美文网首页iOS地图
iOS 区域监听

iOS 区域监听

作者: iOS_成才录 | 来源:发表于2015-11-12 19:31 被阅读640次

    一、基本步骤

    • 1.导入CoreLocation框架和对应的主头文件

       #import <CoreLocation/CoreLocation.h>
      
    • 2.创建CLLcationManager对象,并设置代理,请求授权(iOS8.0之后才需要),请求前后台定位授权,并配置KEY

    pragma mark -懒加载

    -(CLLocationManager *)locationM
    {
    if (!_locationM) {
    _locationM = [[CLLocationManager alloc] init];
    _locationM.delegate = self;

        // 主动请求定位授权
        if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
        [_locationM requestAlwaysAuthorization];
    }
    return _locationM;
    

    }

    + 3.调用CLLcationManager对象的startMonitoringForRegion:方法进行监听指定区域
    
    ```objc
         // 0. 创建一个区域
         // 1.确定区域中心
         CLLocationCoordinate2D center = CLLocationCoordinate2DMake(101.123, 20.345);
         // 确定区域半径
         CLLocationDistance radius = 1000;
         
         // 使用前必须判定当前的监听区域半径是否大于最大可被监听的区域半径
         if(radius > self.locationM.maximumRegionMonitoringDistance)
         {
             radius = self.locationM.maximumRegionMonitoringDistance;
         }
         
         CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:radius identifier:@"JP"];
         // 区域监听
         //    [self.locationM startMonitoringForRegion:region];
         
         // 请求区域状态(如果发生了进入或者离开区域的动作也会调用对应的代理方法)
         [self.locationM requestStateForRegion:region];
    
    • 4.实现代理方法,获取区域进入或者离开等状态
    #pragma mark -CLLocationManagerDelegate
    /**
     *  进入区域调用(是一个动作)
     *
     *  @param manager 位置管理者
     *  @param region  区域
     */
    -(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    {
        NSLog(@"进入区域");
        self.noticeLabel.text = @"进入区域";
    }
    
    /**
     *  离开某个区域调用
     *
     *  @param manager 位置管理者
     *  @param region  区域
     */
    -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    {
         NSLog(@"离开区域");
          self.noticeLabel.text = @" 离开某个区域";
    }
    
    
    /**
     *  请求某个区域的状态是调用
     *
     *  @param manager 位置管理者
     *  @param state   状态
     *  @param region  区域
     */
    -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
    {
    //    CLRegionStateUnknown,   未知状态
    //    CLRegionStateInside, // 在区域内部
    //    CLRegionStateOutside // 区域外面
        if(state == CLRegionStateInside)
        {
            self.noticeLabel.text = @"在区域内部";
        }else if (state == CLRegionStateOutside)
        {
             self.noticeLabel.text = @"区域外面";
        }
    }
    
    /**
     *  监听区域失败时调用
     *
     *  @param manager 位置管理者
     *  @param region  区域
     *  @param error   错误
     */
    -(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
    {
        // 经验: 一般在这里, 做移除最远的区域
    //    [manager stopMonitoringForRegion:最远区域]
    }
    

    二、注意

    • 1.使用前先判断区域监听是否可用
    • 2.注意监听区域的个数 (区域监听个数有上限)
    • 3.注意区域半径是否大于最大监听半径

    三、应用场景

    • 1.结合推送通知使用,可以当用户进入到某个区域内(例如肯德基)之后,向用户推送优惠卡等信息

    四、实现代码

    #import "ViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    @interface ViewController ()<CLLocationManagerDelegate>
    
    /** 位置管理者 */
    @property (nonatomic, strong) CLLocationManager *locationM;
    
    @property (weak, nonatomic) IBOutlet UILabel *noticeLabel;
    
    @end
    
    @implementation ViewController
    
    
    #pragma mark -懒加载
    -(CLLocationManager *)locationM
    {
        if (!_locationM) {
            _locationM = [[CLLocationManager alloc] init];
            _locationM.delegate = self;
            
            // 主动请求定位授权
            if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
            [_locationM requestAlwaysAuthorization];
        }
        return _locationM;
    }
    
    
    - (void)viewDidLoad {
        
        /** 如果想要区域监听, 必须获取用户的定位授权 */
    
        // 监听的区域个数有限制
        
        // 判定某个区域对应的类, 能否被监听
        if([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]])
        {
            // 0. 创建一个区域
            // 1.确定区域中心
            CLLocationCoordinate2D center = CLLocationCoordinate2DMake(101.123, 20.345);
            // 确定区域半径
            CLLocationDistance radius = 1000;
            
            // 使用前必须判定当前的监听区域半径是否大于最大可被监听的区域半径
            if(radius > self.locationM.maximumRegionMonitoringDistance)
            {
                radius = self.locationM.maximumRegionMonitoringDistance;
            }
            
            CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:radius identifier:@"JP"];
            // 区域监听
            //    [self.locationM startMonitoringForRegion:region];
            
            // 请求区域状态(如果发生了进入或者离开区域的动作也会调用对应的代理方法)
            [self.locationM requestStateForRegion:region];
        }
    }
    
    #pragma mark -CLLocationManagerDelegate
    /**
     *  进入区域调用(是一个动作)
     *
     *  @param manager 位置管理者
     *  @param region  区域
     */
    -(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    {
        NSLog(@"进入区域");
        self.noticeLabel.text = @"进入区域";
    }
    
    /**
     *  离开某个区域调用
     *
     *  @param manager 位置管理者
     *  @param region  区域
     */
    -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    {
        NSLog(@"离开区域");
          self.noticeLabel.text = @"离开区域";
    }
    
    
    /**
     *  请求某个区域的状态是调用
     *
     *  @param manager 位置管理者
     *  @param state   状态
     *  @param region  区域
     */
    -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
    {
    //    CLRegionStateUnknown,   未知状态
    //    CLRegionStateInside, // 在区域内部
    //    CLRegionStateOutside // 区域外面
        if(state == CLRegionStateInside)
        {
            self.noticeLabel.text = @"在区域内部";
        }else if (state == CLRegionStateOutside)
        {
             self.noticeLabel.text = @"区域外面";
        }
    }
    
    /**
     *  监听区域失败时调用
     *
     *  @param manager 位置管理者
     *  @param region  区域
     *  @param error   错误
     */
    -(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
    {
        // 经验: 一般在这里, 做移除最远的区域
    //    [manager stopMonitoringForRegion:最远区域]   
    }
    @end
    

    相关文章

      网友评论

      • 043ba7d6dfde:那,要是用户杀死了程序,下一次进入某个区域该怎么做才能监听到呢
      • 85dc92698df7:赞并收藏
      • ibabyblue:您好,我实现的和您几乎一致,就是简单的实现某个区域的监测,但是我每次都是监测失败,调用的报错的代理方法,code为5,我查了一下,意思是:此区域不能监测,但是坐标是我刚刚利用CLLocationManager 定位出来的,请问您遇到过吗?望回答,谢谢! PS:Plist文件已配置。
        WKCaesar:@Cloud_90 错误码为5不是不能监听的意思,你看官方文档,错误码5是你监听的区域数超过20个了(我的代码里面只监听了3个有时也报5,估计是抽风了)

      本文标题:iOS 区域监听

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