ibeacon是基于地理位置的微定位技術(shù)担猛,區(qū)別于BLE收毫。
兩者無任何關(guān)系邑跪。ibeacon使用CoreLocation庫鹊碍,而BLE使用CoreBluetooth庫舆床。
開發(fā)ibeacon需要了解beacon三個(gè)標(biāo)識(shí):
UUID:用來標(biāo)記某一類beacon
major:主要值虑绵,用于區(qū)別子類
minor:次要值丧蘸,用于區(qū)別子類類下一級
如果開發(fā)打卡功能瑟枫。則一般藍(lán)牙硬件都使用同一個(gè)UUID春霍,用于匹配此類beacon砸西,使用major和minor來區(qū)別不同教室。
使用之前需倒入:
import CoreLocation
同時(shí)info.plist文件添加定位權(quán)限:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription
創(chuàng)建IbeaconManager類
直接上代碼:
import UIKit
import CoreLocation
//藍(lán)牙開啟通知
// did centralManager enable notification
let BluetoothNotificationManagerEnable = "BabyNotificationAtCentralManagerEnable"
// 藍(lán)牙彈框是需要彈出
let BluetoothAlertIsShow = "BluetoothAlertIsShow"
// 搜索到設(shè)備數(shù)組
typealias IbeaconSearchResults = (([CLBeacon]) -> ())
class IbeaconManager: NSObject {
static let `default` = IbeaconManager()
var searchResultsCallback: IbeaconSearchResults?
fileprivate var beaconSendRegion: CLBeaconRegion! // 發(fā)送
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()
// 發(fā)射信號(hào)
// 此處代碼用另一部手機(jī)運(yùn)行 模擬ibeacon設(shè)備發(fā)送信號(hào)
beaconSendRegion = CLBeaconRegion(proximityUUID: UUID(uuidString: defaultUUIDString)!, major: 1234, minor: 5678, identifier: beaconIdentifier)
beaconPeripheralData = beaconSendRegion.peripheralData(withMeasuredPower: nil)
peripheraManager = CBPeripheralManager(delegate: self, queue: nil)
// 接受信號(hào)
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 {
//進(jìn)入beacon區(qū)域
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
locationManager.startRangingBeacons(in: beaconReceiveRegion)
print( "進(jìn)入beacon區(qū)域")
}
//離開beacon區(qū)域
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
locationManager.stopRangingBeacons(in: beaconReceiveRegion)
print("離開beacon區(qū)域")
}
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
//返回是掃描到的beacon設(shè)備數(shù)組址儒,這里取第一個(gè)設(shè)備
guard beacons.count > 0 else { return }
self.searchResultsCallback?(beacons)
// 下面為調(diào)試信息
let beacon = beacons.first!
print("major====",beacon.major)
print("minor====",beacon.minor)
//accuracy可以獲取到當(dāng)前距離beacon設(shè)備距離
let location = String(format: "%.3f", beacon.accuracy)
print( "距離第一個(gè)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("藍(lán)牙打開了籍胯!=============================")
print(beaconReceiveRegion.proximityUUID)
print(beaconReceiveRegion.major)
print(beaconReceiveRegion.minor)
print(beaconReceiveRegion.identifier)
print("藍(lán)牙打開了!=============================")
UserDefaults.standard.set(true, forKey: BluetoothNotificationManagerEnable)
UserDefaults.standard.synchronize()
case .poweredOff:
print("藍(lán)牙未打開")
UserDefaults.standard.set(false, forKey: BluetoothNotificationManagerEnable)
UserDefaults.standard.synchronize()
default: peripheraManager.stopAdvertising()
}
}
}
需要使用的地方
/// 開始搜索藍(lán)牙列表 | 只要搜索到了就記錄值 用于對比教師課程里的UUID是否跟這個(gè)一致 | 如果一致說明在藍(lán)牙搜索的范圍內(nèi) 可以執(zhí)行簽到 如果沒有則不在搜索范圍內(nèi)
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")
}
}
// 檢測藍(lán)牙是否打開
if let enable = UserDefaults.standard.value(forKey: BluetoothNotificationManagerEnable) as? Bool {
if enable == false {
blueToothNotOpen?()
}
}else {
blueToothNotOpen?()
}
}
Over !