[筆記] Swift-ibeacon微定位打卡開發(fā)

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 !

參考:
http://www.reibang.com/p/83b9f03316e8

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末离福,一起剝皮案震驚了整個(gè)濱河市杖狼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌妖爷,老刑警劉巖蝶涩,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異絮识,居然都是意外死亡绿聘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門次舌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熄攘,“玉大人,你說我怎么就攤上這事彼念∨不” “怎么了浅萧?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長哲思。 經(jīng)常有香客問我洼畅,道長,這世上最難降的妖魔是什么棚赔? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任帝簇,我火速辦了婚禮,結(jié)果婚禮上靠益,老公的妹妹穿的比我還像新娘丧肴。我一直安慰自己,他們只是感情好胧后,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布闪湾。 她就那樣靜靜地躺著,像睡著了一般绩卤。 火紅的嫁衣襯著肌膚如雪途样。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天濒憋,我揣著相機(jī)與錄音何暇,去河邊找鬼。 笑死凛驮,一個(gè)胖子當(dāng)著我的面吹牛裆站,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播黔夭,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼宏胯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了本姥?” 一聲冷哼從身側(cè)響起肩袍,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎婚惫,沒想到半個(gè)月后氛赐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡先舷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年艰管,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒋川。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡牲芋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情缸浦,我是刑警寧澤夕冲,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站餐济,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胆剧。R本人自食惡果不足惜絮姆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秩霍。 院中可真熱鬧篙悯,春花似錦、人聲如沸铃绒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颠悬。三九已至矮燎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赔癌,已是汗流浹背诞外。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留灾票,地道東北人峡谊。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像刊苍,于是被迫代替她去往敵國和親既们。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容