最近用到iBeacon进行室内定位,发现这东西可以在不打开app的情况下靠近/离开iBeacon设备发送本地推送,根据网上的一些iBeacon教程搞了一天发现并不能触发这个方法,然后各种翻谷歌、论坛解决掉了。
先记录一下iBeacon的基本使用
首先需要一个能发送iBeacon信号的蓝牙芯片或者设备(我用的是一台6s测试机,在AppStore上可以下载一些能发送iBeacon信号的app或者自己写一个)
先创建一个BeaconItem.swift的文件
import CoreLocation
class BeaconItem: NSObject {
let majorValue: CLBeaconMajorValue
let minorValue: CLBeaconMinorValue
let name: String
let uuid: UUID
init(name: String, uuid: UUID,
majorValue: CLBeaconMajorValue,
minorValue: CLBeaconMinorValue) {
self.name = name
self.uuid = uuid
self.majorValue = majorValue
self.minorValue = minorValue
}
}
这是把iBeacon设备的一些数据进行封装
然后在ViewController里面写入(记得要先去Info.plist填写获取CoreLocation相关权限)
import UIKit
import CoreLocation
class ViewController: UIViewController {
let locationManager = CLLocationManager()
let beaconItem = BeaconItem(name: "test", uuid: UUID(uuidString: "FDA50693-A4E2-4FB1-AFCF-C6EB07647825")!, majorValue: 0, minorValue: 0)
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestAlwaysAuthorization()
locationManager.delegate = self
startMonitoring(item: item)
}
/// 根据BeaconItem对象创建CLBeaconRegion
///
/// - Parameter item: BeaconItem
/// - Returns: CLBeaconRegion
func beaconRegionWith(item: BeaconItem) -> CLBeaconRegion {
let beaconRegion = CLBeaconRegion(proximityUUID: item.uuid, major: item.majorValue, minor: item.minorValue, identifier: item.name)
return beaconRegion
}
/// 监听指定的iBeacon设备
///
/// - Parameter item: BeaconItem
func startMonitoring(item: BeaconItem) {
let beaconRegion = beaconRegionWith(item: item)
locationManager.startMonitoring(for: beaconRegion)
locationManager.startRangingBeacons(in: beaconRegion)
}
}
extension ViewController: CLLocationManagerDelegate {
// 检测iBeacon设备的回调
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
for beacon in beacons {
// 可以获取iBeacon的uuid、major、minor、rssi还有距离
}
}
}
靠近/离开推送
通过上面的代码就可以运行监测指定的iBeacon设备的距离,但是如果想做到手机靠近则触发推送的话还需要做以下操作(配置推送这里不做介绍):
在AppDelegate.swift中加入以下内容
import CoreLocation
class AppDelegate: UIResponder, UIApplicationDelegate {
let locationManager = CLLocationManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
locationManager.delegate = self
return true
}
extension AppDelegate: CLLocationManagerDelegate {
// 用户进入iBeacon范围调用
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
// 推送代码
}
// 用户离开iBeacon范围调用
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
// 推送代码
}
}
网上的很多教程基本就这样,然后运行,拿着设备靠近、走开发现根本就不会调用那两个方法,查资料后发现漏了点东西,还需要在刚刚的ViewController里面
startMonitoring(item: item)
这句之前加上
CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self)
CLLocationManager.authorizationStatus()
完整代码如下:
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestAlwaysAuthorization()
locationManager.delegate = self
CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self)
CLLocationManager.authorizationStatus()
startMonitoring(item: item)
}
现在运行就可以达到预想中的效果。