Учитывая возрастающий интерес к использованию Bluetooth маячков в различных областях начиная от чипирования животных, навигации в музейной экспозиции и заканчивая наиболее востребованной функцией уведомлений по акциям в магазинах, мы в Techmas подготовили введение для их внедрения на практике. Возможно, кому-нибудь из разработчиков, кто только планирует создавать свои приложения и еще не знает с чего начать, инструкция ниже поможет разобраться с основными понятиями и возможностями технологии. Несмотря на то, что уже существует набор SDK для работы с маячками, мы используем только Swift и библиотеки CoreLocation и CoreBluetooth.
Начнем с теории по самой технологии. В конце 2014 года Bluetooth Special Interest Group (SIG) выпустила спецификацию Bluetooth v4.2 (Bluetooth Low Energy, BLE).
Следуя описанию, мы имеем сигнал размером в 31 байт в виде пакета Scan Response Data. Этот пакет делится на так называемые AD структуры, которые представляют собой последовательности байтов различных предопределенных размеров. Принимая во внимание, что 16 байт из этого пакета должно уходить на 128 битный UUID устройства, большое количество данных с одного маячка получить нельзя.
Стандарт iBeacon был представлен компанией Apple в 2013 году. В нем сигнал BLE содержит MAC адрес и две AD структуры. Тогда как первая AD структура содержит общую информацию, вторая имеет непосредственное отношение к iBeacon. Рассмотрим ее подробнее.
Первый байт содержит информацию о длине структуры в 26 байт (0x1A), следом один байт на тип, который указывает принадлежность к производителю. Далее идет идентификатор компании Apple (0xFF). Следующие два байта на индикаторы маячка, которые всегда равны 0x02 и 0x15 (по одному байту на каждый). Как мы писали выше, на UUID устройства уходит 16 байт. Итого для полей Major и Minor остается всего по 2 байта. Последнее поле TX Power может быть использовано для калибровки маячка (1 байт).
Общая схема пакета:
Изучив основные понятия, вернемся к SDK от Apple для работы с маячками и напишем простое приложение для вывода информации о ближайшем маячке.
Мы использовали маячки, купленные здесь. Они представляют собой небольшую коробочку размером 46мм*36мм*18мм:
Код примера можно взять в Github.
Итак, начнем с подключения необходимых библиотек:
Далее определим переменные, о назначении которых подробнее скажем позже.
Для простоты, мы в основном будем использовать метод viewDidLoad(). В нем определим:
Объект region определяет область поиска маячков и позволяет ее ограничить по параметрам маячков: uuid, значением полей major и minor.
Далее мы имеем объект locationManager, который обращается к самому устройству для выполнения поиска маячков и отслеживает события их обнаружения. Для этого необходимо назначить наш контроллер делегатом locationManager:
Кроме того, начиная с iOS 8 приложение должно запрашивать авторизацию для использования функций геолокации. Мы можем использовать методы locationManager.requestWhenInUseAuthorization() и locationManager.requestAlwaysAuthorization(). Они отличаются тем, что первый допускает использование геолокации только при активном окне приложения, тогда как второй предоставляет доступ в любое время.
С помощью конструктора добавляем строку в info.plist, который содержится в директории «Supporting Files»:
Чтобы предупреждение не возникало каждый раз, используем метод authorizationStatus() класса CLLocationManager:
Теперь мы готовы к поиску маячков!
Добавляем вызов метода поиска:
Для отображения информации о найденных маячках определим новый метод:
Внутри метода делегата мы имеем доступ к маячкам, которые нашел наш locationManager. Для вывода информации о них в консоль достаточно добавить строку:
Попробуем вывести информацию о ближайшем маячке на экран.
Определим ближайший маячок:
Объект closestBeacon имеет поля, о которых мы упоминали выше:
Остановимся на поле proximity, которое имеет тип enum. Чтобы получить информацию в виде строки нам нужно:
Полученные данные выведем на экран. Код будет выглядеть так:
Наше приложение будет иметь вид:
Надеемся, что наше описание поможет разработчикам быстрее разобраться в технологии iBeacon и начать создавать новые приложения. В следующих статьях мы расскажем как подготовить структуру навигации внутри помещений с помощью набора маячков, использовать уведомления при попадании в зону сигнала и многое другое.
Начнем с теории по самой технологии. В конце 2014 года Bluetooth Special Interest Group (SIG) выпустила спецификацию Bluetooth v4.2 (Bluetooth Low Energy, BLE).
Следуя описанию, мы имеем сигнал размером в 31 байт в виде пакета Scan Response Data. Этот пакет делится на так называемые AD структуры, которые представляют собой последовательности байтов различных предопределенных размеров. Принимая во внимание, что 16 байт из этого пакета должно уходить на 128 битный UUID устройства, большое количество данных с одного маячка получить нельзя.
Стандарт iBeacon был представлен компанией Apple в 2013 году. В нем сигнал BLE содержит MAC адрес и две AD структуры. Тогда как первая AD структура содержит общую информацию, вторая имеет непосредственное отношение к iBeacon. Рассмотрим ее подробнее.
Первый байт содержит информацию о длине структуры в 26 байт (0x1A), следом один байт на тип, который указывает принадлежность к производителю. Далее идет идентификатор компании Apple (0xFF). Следующие два байта на индикаторы маячка, которые всегда равны 0x02 и 0x15 (по одному байту на каждый). Как мы писали выше, на UUID устройства уходит 16 байт. Итого для полей Major и Minor остается всего по 2 байта. Последнее поле TX Power может быть использовано для калибровки маячка (1 байт).
Общая схема пакета:
Изучив основные понятия, вернемся к SDK от Apple для работы с маячками и напишем простое приложение для вывода информации о ближайшем маячке.
Мы использовали маячки, купленные здесь. Они представляют собой небольшую коробочку размером 46мм*36мм*18мм:
Код примера можно взять в Github.
Итак, начнем с подключения необходимых библиотек:
import UIKit
import CoreLocation
import CoreBluetooth
Далее определим переменные, о назначении которых подробнее скажем позже.
var locationManager = CLLocationManager()
var region = CLBeaconRegion()
Для простоты, мы в основном будем использовать метод viewDidLoad(). В нем определим:
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
}
Объект region определяет область поиска маячков и позволяет ее ограничить по параметрам маячков: uuid, значением полей major и minor.
let region = CLBeaconRegion(proximityUUID: NSUUID(UUIDString: "E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"), identifier: "ru.techmas.techbeacon")
Далее мы имеем объект locationManager, который обращается к самому устройству для выполнения поиска маячков и отслеживает события их обнаружения. Для этого необходимо назначить наш контроллер делегатом locationManager:
class ViewController: UIViewController, CLLocationManagerDelegate {
Кроме того, начиная с iOS 8 приложение должно запрашивать авторизацию для использования функций геолокации. Мы можем использовать методы locationManager.requestWhenInUseAuthorization() и locationManager.requestAlwaysAuthorization(). Они отличаются тем, что первый допускает использование геолокации только при активном окне приложения, тогда как второй предоставляет доступ в любое время.
С помощью конструктора добавляем строку в info.plist, который содержится в директории «Supporting Files»:
Чтобы предупреждение не возникало каждый раз, используем метод authorizationStatus() класса CLLocationManager:
if (CLLocationManager.authorizationStatus() != CLAuthorizationStatus.AuthorizedWhenInUse) {
locationManager.requestWhenInUseAuthorization()
}
Теперь мы готовы к поиску маячков!
Добавляем вызов метода поиска:
locationManager.startRangingBeaconsInRegion(region)
Для отображения информации о найденных маячках определим новый метод:
func locationManager(manager: CLLocationManager!, didRangeBeacons beacons: [AnyObject]!, inRegion region: CLBeaconRegion!) {
}
Внутри метода делегата мы имеем доступ к маячкам, которые нашел наш locationManager. Для вывода информации о них в консоль достаточно добавить строку:
println(beacons)
Попробуем вывести информацию о ближайшем маячке на экран.
Определим ближайший маячок:
let knownBeacons = beacons.filter{ $0.proximity != CLProximity.Unknown }
if (knownBeacons.count > 0) {
let closestBeacon = knownBeacons[0] as! CLBeacon
}
Объект closestBeacon имеет поля, о которых мы упоминали выше:
- major
- minor
- proximity
- rssi
- accuracy
Остановимся на поле proximity, которое имеет тип enum. Чтобы получить информацию в виде строки нам нужно:
var proximityString = String()
switch proximity
{
case .Near:
proximityString = "Близко"
case .Immediate:
proximityString = "Недалеко"
case .Far:
proximityString = "Далеко"
case .Unknown:
proximityString = "Unknown"
}
Полученные данные выведем на экран. Код будет выглядеть так:
func locationManager(manager: CLLocationManager!, didRangeBeacons beacons: [AnyObject]!, inRegion region: CLBeaconRegion!) {
println(beacons)
let knownBeacons = beacons.filter{ $0.proximity != CLProximity.Unknown }
if (knownBeacons.count > 0) {
let closestBeacon = knownBeacons[0] as! CLBeacon
major_label.text = String(stringInterpolationSegment: closestBeacon.major)
minor_label.text = String(stringInterpolationSegment: closestBeacon.minor)
let proximity = closestBeacon.proximity
var proximityString = String()
switch proximity
{
case .Near:
proximityString = "Близко"
case .Immediate:
proximityString = "Недалеко"
case .Far:
proximityString = "Далеко"
case .Unknown:
proximityString = "Unknown"
}
proximity_label.text = proximityString
rssi_label.text = String(closestBeacon.rssi)
accuracy_label.text = String(stringInterpolationSegment: closestBeacon.accuracy)
}
}
Наше приложение будет иметь вид:
Надеемся, что наше описание поможет разработчикам быстрее разобраться в технологии iBeacon и начать создавать новые приложения. В следующих статьях мы расскажем как подготовить структуру навигации внутри помещений с помощью набора маячков, использовать уведомления при попадании в зону сигнала и многое другое.
Комментарии (2)
barsuga
12.08.2015 18:16От момента оформления заказа до получения в Москве прошло около месяца.
Нет, не только. В статье Swift и iOS рассмотрены для примера.
andrewsch
Долго дожидались, пока маячки доехали из Китая?
И вы только iPhone собираетесь подключать?