前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS区域监控(地理围栏)

iOS区域监控(地理围栏)

作者头像
用户6094182
发布2019-08-23 17:42:11
1.4K0
发布2019-08-23 17:42:11
举报
文章被收录于专栏:joealzhou

iOS区域监控(地理围栏)

区域监控,高德地图上叫地理围栏,两者都是同一个意思。此功能实现的是:首先创建一个区域(围栏),当用户设备进入或者离开此区域时,会有相应的代理方法响应,开发者可以做一些操作。并且最重要的一点是当开启了区域监控,即使用户杀死了APP还是可以监听到代理方法的响应,从而做一些操作。

地理围栏.jpg

位置权限:必须是始终运行访问地理位置权限,这样在杀死状态下才能通过区域监控唤醒APP获取位置信息。

开始我接入的是高德SDK,但不知是何原因导致我杀死APP时地理围栏并没有唤醒APP。所以我换成了系统CoreLocation框架实现此功能。

一、导入框架

代码语言:javascript
复制
import CoreLocation

二、初始化CLLocationManager

代码语言:javascript
复制
locationManager = CLLocationManager()
locationManager.delegate = self
//必须满足始终允许地理位置访问
locationManager.requestAlwaysAuthorization()
locationManager.pausesLocationUpdatesAutomatically = false
if #available(iOS 9.0, *) {
    locationManager.allowsBackgroundLocationUpdates = true
} else {
    // Fallback on earlier versions
}

三、遵从代理CLLocationManagerDelegate

代码语言:javascript
复制
// MARK: - 区域监控代理方法
extension AppLocationManager {
    
    /// 进入区域
    func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
        debugPrint("进入区域")
    }
    
    /// 离开区域
    func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
        debugPrint("离开区域")
    }
    
    /// 请求某个区域的状态
    func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
        //    CLRegionStateUnknown,   未知状态
        //    CLRegionStateInside, // 在区域内部
        //    CLRegionStateOutside // 区域外面
        var msg = ""
        if(state == .inside)
        {
            debugPrint("在区域内")
            msg = "在区域内"
        }else if (state == .outside)
        {
            debugPrint("在区域外")
             msg = "在区域外"
        } else {
            debugPrint("未知区域")
             msg = "未知区域"
        }
        //发送本地推送
        LocalNotificationManager.addNotification(msg: msg)
    }
    
    /// 监听区域失败
    func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {
        // 经验: 一般在这里, 做移除最远的区域
        //    [manager stopMonitoringForRegion:最远区域]
        debugPrint(error)
    }
}

四、区域定位唤醒被杀死APP

当用户设置始终允许访问地理位置权限时,即使APP被杀死了,当进入区域或者离开区域时都能唤醒APP,这时我们就可以在AppDelegate方法中func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool判断是否是区域定位唤醒的从而做一些操作。

代码语言:javascript
复制
/// APP被唤醒机制
    func awakeForRegion(launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
        let flag = launchOptions?.keys.contains(UIApplication.LaunchOptionsKey.location) ?? false
        if flag {
            LocalNotificationManager.addNotification(msg: "被区域定位唤醒")
        }
        let isNotification = launchOptions?.keys.contains(UIApplication.LaunchOptionsKey.remoteNotification) ?? false
        if isNotification {
            LocalNotificationManager.addNotification(msg: "被通知推送唤醒")
        }
    }

五、开启区域监控

做好了以上步骤就可以实现区域监控代码了,区域监控顾名思义就是要划定一个区域,系统给我们提供了好几种划定区域的方法,我们选择最简单的一种--画圆。

代码语言:javascript
复制
/// 开启区域定位
    func regionWatch() {
        if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
            guard let lat = AppLoginUserManager.default.dormLat, let lng = AppLoginUserManager.default.dormLng else {
                return
            }
            guard lat > 0 && lng > 0 else { return }
            var center = CLLocationCoordinate2DMake(lat, lng)
//            中国国测局地理坐标(GCJ-02) 转换成 世界标准地理坐标(WGS-84)
//              这里是因为我们使用的是国内的坐标系统,但是iOS系统获取的是世界标注坐标系统所以我们需要转换一下
//              如果你们后端提供的坐标也是世界标准的话就不需要转化了
//              JZLocationConverter是一个第三方库:https://github.com/JackZhouCn/JZLocationConverter
            center = JZLocationConverter.gcj02(toWgs84: center)
            var radius: Double = 20
            
            if let r = AppLoginUserManager.default.locationRadius, r > 0 {
                radius = r
            }
                //判断半径是否超过系统的最大
            if radius > self.locationManager.maximumRegionMonitoringDistance {
                radius = self.locationManager.maximumRegionMonitoringDistance
            }
            let region = CLCircularRegion(center: center, radius: radius, identifier: "NZ")
            //监听进入区域
            region.notifyOnEntry = true
            //监听离开区域
            region.notifyOnExit = true
            //开始区域监听
            locationManager.startMonitoring(for: region)
            locationManager.requestState(for: region)
        }
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.06.12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • iOS区域监控(地理围栏)
    • 一、导入框架
      • 二、初始化CLLocationManager
        • 三、遵从代理CLLocationManagerDelegate
          • 四、区域定位唤醒被杀死APP
            • 五、开启区域监控
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档