iBeacon 是蘋果公司在 iOS 7 中新推出的一種近場定位技術(shù),可以感知一個附近的 iBeacon 信標(biāo)的存在。
當(dāng)一個 iBeacon 兼容設(shè)備進(jìn)入/退出一個 iBeacon 信標(biāo)標(biāo)識的區(qū)域時,iOS 和支持 iBeacon 的 app 就能得知這一信息,從而對用戶發(fā)出相應(yīng)的通知。
典型的應(yīng)用場景例如博物館實時推送附近展品的相關(guān)信息,商場內(nèi)即時通知客戶折扣信息等。蘋果在 Apple Store 中也部署了 iBeacon 來推送優(yōu)惠、活動信息。
iBeacon 基于低功耗藍(lán)牙技術(shù)(Bluetooth Low Energy, BLE)這一開放標(biāo)準(zhǔn),因此也繼承了 BLE 的一些特點。
范圍廣
相比于 NFC 的數(shù)厘米的識別范圍,iBeacon 的識別范圍可以達(dá)到數(shù)十米,并且能夠估計距離的遠(yuǎn)近。
兼容性
iBeacon 是基于 BLE 做的一個簡單封裝,因此大部分支持 BLE 的設(shè)備都可以兼容。 例如可以使用一個普通的藍(lán)牙芯片作為信標(biāo),使用 Android 設(shè)備檢測信標(biāo)的存在。
低能耗
不少 beacon 實現(xiàn)宣稱可以不依賴外部能源獨立運行兩年。
我們以一個連鎖商場的例子來講解 iBeacon 的一個流程。在一個連鎖商場中,店家需要在商場中的不同地方推送不同的優(yōu)惠信息,比如服裝和家居柜臺推送的消息就很有可能不同。
當(dāng)消費者走進(jìn)某個商場時,會掃描到一個 beacon。這個 beacon 有三個標(biāo)志符,proximityUUID
是一個整個公司(所有連鎖商場)統(tǒng)一的值,可以用來標(biāo)識這個公司,major
值用來標(biāo)識特定的連鎖商場,比如消費者正在走進(jìn)的商場,minor
值標(biāo)識了特定的一個位置的 beacon,例如定位到消費者正在門口。
這時商場的 app 會被系統(tǒng)喚醒,app 可以運行一個比較短的時間。在這段時間內(nèi),app 可以根據(jù) beacon 的屬性查詢到用戶的地理位置(通過查詢服務(wù)器或者本地數(shù)據(jù)),例如在化妝品專柜,之后就可以通過一個 local notification 推送化妝品的促銷信息。用戶可以點擊這次 local notification 來查看更詳細(xì)的信息,這樣一次促銷行為就完成了。
閑話少說,我們來看下 iBeacon 具體怎么使用:
iBeacon 本質(zhì)上來說是一個位置(區(qū)域)信息,所以 Apple 把 iBeacon 功能集成在了 Core Location 里面。
iBeacon 信標(biāo)在 Core Location 中表現(xiàn)為一個 CLBeacon
,它圈定的范圍則表現(xiàn)為 CLBeaconRegion
,這是一個 CLRegion
的子類。
CLBeaconRegion
主要用三個屬性來標(biāo)識一個 iBeacon,proximityUUID
、major
和 minor
。
proximityUUID
是一個 NSUUID
,用來標(biāo)識公司,每個公司、組織使用的 iBeacon 應(yīng)該擁有同樣的 proximityUUID
。
major
用來識別一組相關(guān)聯(lián)的 beacon,例如在連鎖超市的場景中,每個分店的 beacon 應(yīng)該擁有同樣的 major
。
minor
則用來區(qū)分某個特定的 beacon。
這些屬性如果不指定(即 nil),匹配的時候就會忽略這個屬性。例如只指定 proximityUUID
的 CLBeaconRegion
可以匹配某公司的所有 beacons。
Apple 在 iOS 4 中增加了地理圍欄 API,可以用來在設(shè)備進(jìn)入/退出某個地理區(qū)域時獲得通知,這些 API 包括 -startMonitoringForRegion:
、-locationManager:didEnterRegion:
、-locationManager:didExitRegion:
等。 CLBeaconRegion
作為 CLRegion
的子類也可以復(fù)用這些 API,這種檢測 iBeacon 的方式叫做 monitoring。
使用這種方法可以在程序在后臺運行時檢測 iBeacon,但是只能同時檢測 20 個 region,也不能推測設(shè)備與 beacon 的距離。
除了使用地理圍欄 API 的方式,Apple 還在 iOS 7 中新增加了 iBeacon 專用的檢測方式,也就是 ranging。
通過 CLLocationManager
的 -startRangingBeaconsInRegion:
方法可以開始檢測特定的 iBeacon。
當(dāng)檢測到 beacon 的時候,CLLocationManager
的 delegate 方法 -locationManager:didRangeBeacons:inRegion:
會被調(diào)用,通知調(diào)用者現(xiàn)在被檢測到的 beacons。 這個方法會返回一個 CLBeacon
的數(shù)組,根據(jù) CLBeacon
的 proximity
屬性就可以判斷設(shè)備和 beacon 之間的距離。
proximity
屬性有四個可能的值,unknown、immediate、near 和 far。 另外 CLBeacon
還有 accuracy
和 rssi
兩個屬性能提供更詳細(xì)的距離數(shù)據(jù)。
我們可以使用 Core Bluetooth 框架來廣播特定的 payload 來讓 iOS 設(shè)備成為一個 iBeacon。 這個 payload 可以由 CLBeaconRegion
的 -peripheralDataWithMeasuredPower:
方法來獲取。
之后交給 CBPeripheralManager
廣播出去就可以了。
需要注意的是,廣播 iBeacon 信息的時候 app 必須在前臺運行。
iBeacon 的 API 并不十分復(fù)雜,但他的行為比較難弄清楚,特別是當(dāng)應(yīng)用運行在后臺時,檢測到 beacon 的時間延遲會讓開發(fā)者難以推測。在做了一些實驗和合理的推測后,我們得出了一些結(jié)論:
notifyEntryStateOnDisplay=YES
的 beacon,iOS 會在屏幕點亮的時候(鎖屏狀態(tài)下按下 home 鍵,或者因為收到推送點亮等)進(jìn)行一次掃描。2018-03-01
2015-01-28
2015-11-28