Підводні камені використання Cocoa Touch BLE

Будь-який розробник, який працював з iOS BLE, знає, що насправді не все так чудово, як описує документація. Сьогодні я хотів би розповісти про кілька основних моментів, які можуть виявитись каверзними під час роботи з BLE. Поділюся з вами корисною інформацією, аби зробити вашу подорож до світу Cocoa BLE менш болючою та більш продуктивною.

Скорочення (у порядку їх появи в тексті):

BLE — Bluetooth Low Energy — технологія Bluetooth з низьким енергоспоживанням
PCB — Printed circuit board — друкована плата
API — Application Programming Interface — програмний інтерфейс застосунку

Основні підходи

Найперше, що вам треба знати, — це відповідь на питання: «Де саме щось іде не так — на вашому боці чи на підключеному пристрої?».

Щоб відповісти на це питання, я рекомендую застосовувати кілька підходів:

Тож давайте обговоримо кожен підхід детальніше.

Сніффер

Це інструмент, що дозволяє вам перехоплювати пакети даних та аналізувати їх напряму за допомогою спеціального застосунку. Він може бути корисним, щоб розрізняти різні аспекти BLE-комунікації — запити, відповіді, необроблені помилки, несподівані повідомлення і таке інше.

Щоб встановити такий інструмент, вам потрібно лише кілька промов: спеціальна PCB-плата та відповідний застосунок. Я використовував Wireshark та тестову плату Nordic Semiconductors. Разом вони забезпечують потужний набір інструментів для сніффингу. Інструменти-сніффери можуть бути використані в двох режимах — реклами та з'єднання єднання.

Корисні посилання:

Сторонні програми для тестування API

Один з найшвидших способів перевірки вашого пристрою — це використання сторонніх рішень. З їх допомогою ви легко можете сканувати, надсилати/отримувати або навіть симулювати деякі функції вашого пристрою. Чудові приклади: LightBlue , BlueGecko .

Ведення ловга

Більшість BLE-пристроїв комунікують зі смартфоном. Тому розуміти, що відбувається власне на телефоні, може бути надзвичайно важливим і корисним. Один з найкращих способів для перевірки того, що відбувається у телефоні, — використання можливостей власне операційної системи телефону, реєструючи всі події в лог. Щоб активувати ведення логу для Bluetooth в iOS, потрібно встановити спеціальний профіль на пристрій. Більше інформації про це можна знайті тут .

Після активації iTunes зможе синхронізувати логи з комп'ютером для їх подальшого аналізу.

Прошивка

Щоб захистити свій продукт, виробники часто використовують зашифрований протокол зв'язку між програмою та пристроєм. Такий підхід забезпечує більш високий рівень безпеки для користувача, однак він набагато складніший в розробці. Щоб спростити цей процес, завжди використовуйте незашифровану версію прошивки під час розробки та включайте додатковий рівень безпеки лише при виведенні на ринок. Це, звичайно, дещо впливає на годину розробки прошивки, але водночас зменшує зусилля, необхідні з вашого боку для розробки застосунку.

На цьому етапі я припускаю, що середовище розробки повністю працює, і все, що вам треба, це просто засукати рукава та почати програмувати :)

Про що подбати

Щоб гарантувати вашу користувачеві найкращий user experience, ви повинні повністю контролювати середовище Bluetooth всередині вашої програми та, відповідно, у всіх його аспектах. Загалом ви повинні подбати про такі моменти:

Я не буду описувати всі аспекти шкірного з наведених вище моментів. Замість цього я поділюся з вами кількома порадами та власними спостереженнями.

Спостереження за статусом прилаштую

На наше щастя, iOS вміє працювати з кількома пристроями одночасно. Тож при роботі з кількома об'єктами, що працюють з Bluetooth-пристроями, ніяких проблем не виникає. Звичайно ж, ми скористаємося цією можливістю. Один з можливих підходів — це підготувати простий сканер стану Bluetooth, що дозволить вам отримувати сповіщення при зміні статусу. Цей підхід простий, ефективний і може бути використаний таким чином:

import Foundation
import CoreBluetooth

final class BLEStatusObserver: NSObject {

 public struct Notifications {
 public static let BLEStatusObserverDidDetectBLEStatuschange = "BLEStatusObserverDidDetectBLEStatuschangenotification"

 struct Keys {
 static let availability = "availability"static let message = "message"
}
}
 static let observer = BLEStatusObserver()

 var isBleDeviceActive:Bool {
 return currentState == .poweredOn
}
 private var centralManager:CBCentralManager?
 private var currentState:CBManagerState = .unknown

 // MARK: - LifeCycle

 override init() {
super.init()

 centralManager = CBCentralManager(delegate: self, queue: nil)
}
}

extension BLEStatusObserver:CBCentralManagerDelegate {
 // MARK: - CBCentralManagerDelegate

 func centralManagerDidUpdateState(_ central: CBCentralManager) {
 var notificationMessage:String? = nilswitch central.state {
 case .unauthorized:
 notificationMessage = NdynamicLocalizableString"bleService.message.StatusUnathorized")
 case .unsupported:
 notificationMessage = NdynamicocalizableString("bleService.message.Unsupported")
 case .poweredOff:
 notificationMessage = NdynamicocalizableString("bleService.message.PowerOff")
 case .poweredOn:
 notificationMessage = NdynamicocalizableString("bleService.message.PowerOn")
default:
break
}

 currentState = central.state

 NotificationCenter.default.post(name: NSNotification.Name(rawValue: BLEStatusObserver.Notifications.BLEStatusObserverDidDetectBLEStatuschange), 
 object: nil, userInfo: [
 Notifications.Keys.availability : central.state == .poweredOn,
 Notifications.Keys.message : notificationMessage ?? ""
])
}
}

Тайм-аут

Тайм-аут для запитів від BLE не обробляється CoreBluetooth за замовчуванням, тому вам доведеться реалізувати цей механізм самостійно. Вісь де ви зможете втілити весь свій творчий потенціал в рамках проектних вимог. Єдине, що вам насправді треба знати, — тайм-аут насправді необхідний (навіть коли все здавалось б працює бездоганно).

Ще один корисний момент — це знання про швидкість передачі пакетів даних та відповідні взаємозалежності. Хтось, напевне, вже підготував тести на справжніх пристроях. Також у вас, можливо, з'явиться бажання перевірити офіційну документацію Bluetooth. Припускаю, швидкість передачі пакетів може залежати від кількох факторів:

Беручи це до уваги, пропоную починати з 70-100 мілісекунд, а потім адаптувати цей годину до ваших потреб.

Багаторядкові відповіді

Деякі прошивки можуть для конкретних запитів повертати відповідь довжиною у кілька рядків (через обмеження розміру пакету, особливості реалізації або з іншої причини). У такому разі я хотів би запропонувати узгоджувати конкретний протокол зв'язку та структуру шкірного запиту/відповіді. Наприклад, це може бути таким чином:

Цей підхід надзвичайно простий та, повірте мені, дуже ефективний. Якщо ви його запровадите, ві можете навіть почати краще спати вночі :)

Ще один момент — переконайтесь, що ви виконуєте лише один запит одночасно. Для цього у пригоді може стати NSOperationQueue. Я не поринатиму в особливості реалізації, проте хочу наголосити, що, аби належний чином обробляти усі моменти, слід створити щось на кшталт AsyncOperation (наприклад, як відпрасована). ).

Робота у фоновому режимі

А вісь це надзвичайно цікаво. Серйозно — дуже і дуже цікаво. Слід прочитати усю наявну документацію, а потім прочитати її ще раз. Чимало моментів можуть виявитись дещо підступними. Я не описуватиму всі складнощі тут, бо вважаю, що це питання для окремої статті, наприклад, такої .

Все, що вам слід знати про роботу у фоновому режимі для Cocoa Touch — це ті, що все дійсно працює, але не завжди так, як ви очікуєте. Якщо ви стикнулися з труднощами, є лише одна порада — читати документацію ще раз.

Висновки

Використавши наведені підходи при роботі з BLE в CocoaTouch, ви з легкістю збережете свій час та підвищите ефективність своєї роботи. Звісно, багато моментів тут не розкриті на повну, проте наведені ресурси та посилання допоможуть знайті правильний шлях для коректного вирішення будь-яких поставлених завдань. І на останок скажу, що по-хорошому заздрю тому, хто буде вперше починати працювати з BLE в Cocoa, тому побажаю терпіння і натхнення :)

Корисні посилання:

Опубліковано: 25/05/18 @ 10:04
Розділ Різне

Рекомендуємо:

DOU Проектор: RoboBus — мобільна школа програмування та робототехніки
Які подкасти слухають IT-фахівці
Як змусити себе працювати: боремося з прокрастинацією
AI & ML дайджест #7: самоврядні машини, Data Science як сучасна алхімія, PyTorch 1.0
PHP дайджест #13: реліз 7.3, що нас чекає в PHP 8 та майбутнє програмування