ibeacon是基于地理位置的微定位技术,区别于BLE。
两者无任何关系。ibeacon使用CoreLocation库,而BLE使用CoreBluetooth库。
开发ibeacon需要了解beacon三个标识:
UUID:用来标记某一类beacon
major:主要值,用于区别子类
minor:次要值,用于区别子类类下一级
如果开发打卡功能。则一般蓝牙硬件都使用同一个UUID,用于匹配此类beacon,使用major和minor来区别不同教室。
使用之前需倒入:
import CoreLocation
同时info.plist文件添加定位权限:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription
创建IbeaconManager类
直接上代码:
import UIKit
import CoreLocation
//蓝牙开启通知
// did centralManager enable notification
let BluetoothNotificationManagerEnable = "BabyNotificationAtCentralManagerEnable"
// 蓝牙弹框是需要弹出
let BluetoothAlertIsShow = "BluetoothAlertIsShow"
// 搜索到设备数组
typealias IbeaconSearchResults = (([CLBeacon]) -> ())
class IbeaconManager: NSObject {
static let `default` = IbeaconManager()
var searchResultsCallback: IbeaconSearchResults?
fileprivate var beaconSendRegion: CLBeaconRegion! // 发送
fileprivate var beaconReceiveRegion: CLBeaconRegion! // 接受
fileprivate var locationManager: CLLocationManager!
fileprivate var beaconPeripheralData: NSDictionary!
fileprivate var peripheraManager: CBPeripheralManager!
var location: Float = 0.0 //距离
let beaconIdentifier = "ibeaconTest"
let defaultUUIDString = "XXXX-XXXXXX-XXXXXX-XXXXXXXXXX"
override init() {
super.init()
// 发射信号
// 此处代码用另一部手机运行 模拟ibeacon设备发送信号
beaconSendRegion = CLBeaconRegion(proximityUUID: UUID(uuidString: defaultUUIDString)!, major: 1234, minor: 5678, identifier: beaconIdentifier)
beaconPeripheralData = beaconSendRegion.peripheralData(withMeasuredPower: nil)
peripheraManager = CBPeripheralManager(delegate: self, queue: nil)
// 接受信号
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
beaconReceiveRegion = CLBeaconRegion(proximityUUID: UUID(uuidString: defaultUUIDString)!, identifier: beaconIdentifier)
beaconReceiveRegion.notifyEntryStateOnDisplay = true
//请求一直允许定位
locationManager.requestAlwaysAuthorization()
beaconReceiveRegion.notifyEntryStateOnDisplay = true
}
/// 开始扫描
func startRunningBeacons() {
//开始扫描
locationManager.startMonitoring(for: beaconReceiveRegion)
locationManager.startRangingBeacons(in: beaconReceiveRegion)
}
}
extension IbeaconManager: CLLocationManagerDelegate {
//进入beacon区域
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
locationManager.startRangingBeacons(in: beaconReceiveRegion)
print( "进入beacon区域")
}
//离开beacon区域
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
locationManager.stopRangingBeacons(in: beaconReceiveRegion)
print("离开beacon区域")
}
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
//返回是扫描到的beacon设备数组,这里取第一个设备
guard beacons.count > 0 else { return }
self.searchResultsCallback?(beacons)
// 下面为调试信息
let beacon = beacons.first!
print("major====",beacon.major)
print("minor====",beacon.minor)
//accuracy可以获取到当前距离beacon设备距离
let location = String(format: "%.3f", beacon.accuracy)
print( "距离第一个beacon\(location)m")
}
func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {
print("Failed monitoring region: \(error.localizedDescription)")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Location manager failed: \(error.localizedDescription)")
}
}
extension IbeaconManager: CBPeripheralManagerDelegate {
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
switch peripheral.state {
case .poweredOn:
peripheraManager.startAdvertising(beaconPeripheralData as? [String : Any])
print("蓝牙打开了!=============================")
print(beaconReceiveRegion.proximityUUID)
print(beaconReceiveRegion.major)
print(beaconReceiveRegion.minor)
print(beaconReceiveRegion.identifier)
print("蓝牙打开了!=============================")
UserDefaults.standard.set(true, forKey: BluetoothNotificationManagerEnable)
UserDefaults.standard.synchronize()
case .poweredOff:
print("蓝牙未打开")
UserDefaults.standard.set(false, forKey: BluetoothNotificationManagerEnable)
UserDefaults.standard.synchronize()
default: peripheraManager.stopAdvertising()
}
}
}
需要使用的地方
/// 开始搜索蓝牙列表 | 只要搜索到了就记录值 用于对比教师课程里的UUID是否跟这个一致 | 如果一致说明在蓝牙搜索的范围内 可以执行签到 如果没有则不在搜索范围内
func startBlueToothSearch(blueToothNotOpen: (()->())?) {
IbeaconManager.default.startRunningBeacons()
IbeaconManager.default.searchResultsCallback = { (ibeacons) in
var location = Double(1000)
for ibeacon in ibeacons {
let majorMinor = "\(ibeacon.major)\(ibeacon.minor)"
// 值越小代表距离最近 ibeacon.accuracy 为距离
if ibeacon.accuracy <= location {
location = ibeacon.accuracy
}
print("major====",ibeacon.major)
print("minor====",ibeacon.minor)
let location = String(format: "%.3f", ibeacon.accuracy)
print( "距离beacon====\(location)m")
}
}
// 检测蓝牙是否打开
if let enable = UserDefaults.standard.value(forKey: BluetoothNotificationManagerEnable) as? Bool {
if enable == false {
blueToothNotOpen?()
}
}else {
blueToothNotOpen?()
}
}
Over !