Користувач купив розумний датчик температури T200, а наклейка з QR-кодом стерлася — знайома ситуація. Без QR додавання пристрою за серійним номером стає основним способом, який виручає в таких випадках. Ми реалізуємо цей процес з акцентом на UX і надійність: введення або сканування, локальна валідація формату, пошук у хмарі та двоетапна прив'язка до акаунта. Наш досвід у мобільній розробці — понад 5 років, 10+ IoT-проєктів — дозволяє передбачити всі нюанси, від маски введення до обробки помилок API.
Серійний номер — унікальний ідентифікатор пристрою, надрукований на корпусі. На відміну від QR, він не псується з часом, але потребує акуратного введення. Помилка в одному символі — і пристрій не знайдеться. Тому ми приділяємо особливу увагу UX: маска введення, сканування камерою, inline-валідація. Сканування камерою скорочує час введення з 10 до 1 секунди — економія до 90% часу користувача. Локальна валідація знижує кількість некоректних запитів до сервера на 30%.
Формати серійних номерів
У кожного виробника свій формат:
-
SN-XXXXXXXX— 8 hex-символів після префікса -
AAAA-BBBB-CCCC-DDDD— групи по 4 символи (аналог ключа активації) - MAC-адреса як серійний номер —
AA:BB:CC:DD:EE:FF - Числовий код —
12345678901
Формат потрібно знати заздалегідь — він визначає маску введення та валідатор. Якщо серійний номер завжди 12 символів, користувач не повинен вгадувати — поле введення має показувати маску та приймати лише потрібний формат.
Як реалізувати маску введення для серійного номера?
Ключові вимоги до поля серійного номера:
-
Автокапс і автокорекцію — вимкнути.
inputType="textNoSuggestions|textCapCharacters"на Android. На iOS:autocorrectionType = .no,autocapitalizationType = .allCharacters. Автокорекція перетворюєABC123наAbc123— пристрій не знайдеться.
Маска введення. Для формату XXXX-XXXX-XXXX — вставляти дефіси автоматично під час введення. На Android: TextWatcher з обробкою позиції курсора:
editText.addTextChangedListener(object : TextWatcher { private var isFormatting = false override fun afterTextChanged(s: Editable) { if (isFormatting) return isFormatting = true val digits = s.toString().filter { it.isLetterOrDigit() }.uppercase() val formatted = digits.chunked(4).joinToString("-").take(14) s.replace(0, s.length, formatted) isFormatting = false } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} }) Сканування камерою як альтернатива введенню. Серійний номер часто надрукований штрихкодом на задній панелі пристрою. Кнопка «Сканувати» поруч із полем введення. Використовуємо ML Kit або ZXing для Code 128 / Code 39.
| Критерій | Ручне введення | Сканування камерою |
|---|---|---|
| Швидкість | ~10 секунд | ~1 секунда (в 10 разів швидше) |
| Помилки введення | ~10% | менше 1% (точність 99%) |
| Витрати на розробку | Нижчі | Вищі, але окупаються за рахунок UX |
Чому важлива локальна валідація?
Локальна валідація відсікає свідомо невірні введення до звернення до сервера, знижуючи навантаження на бекенд на 30% і прискорюючи зворотний зв'язок. Для користувача це означає менше очікування.
fun validateSerialNumber(input: String): ValidationResult { val clean = input.filter { it.isLetterOrDigit() }.uppercase() return when { clean.length < 8 -> ValidationResult.TooShort clean.length > 16 -> ValidationResult.TooLong !clean.matches(Regex("[A-Z0-9]+")) -> ValidationResult.InvalidChars else -> ValidationResult.Valid(clean) } } Помилку валідації показуємо inline — під полем введення, не в alert. Користувач бачить проблему одразу і виправляє, не втрачаючи введені дані.
Двоетапна прив'язка через API
Крок 1 — пошук пристрою:
GET /api/devices/lookup?serial=ABC12345678 Відповідь: тип пристрою, модель, статус (вільний / уже прив'язаний до іншого акаунта / не існує). Показуємо користувачеві, що саме знайдено — «Датчик температури модель T200» — до підтвердження прив'язки.
Крок 2 — прив'язка:
POST /api/devices/claim { "serial": "ABC12345678", "name": "Датчик на балконі" } Серійний номер не дорівнює claim-токену — це різні речі. Серійний номер публічний, за ним знаходять пристрій. Прив'язка вимагає аутентифікації користувача (JWT у заголовку), інакше будь-хто міг би викрасти пристрій.
Обробка помилок
| Статус | Що показати користувачеві |
|---|---|
| 404 Not Found | «Пристрій з таким серійним номером не знайдено. Перевірте введення» |
| 409 Conflict | «Цей пристрій уже прив'язаний до іншого акаунта» |
| 422 Unprocessable | «Невірний формат серійного номера» |
| 503 Service Unavailable | «Сервіс тимчасово недоступний. Спробуйте пізніше» |
Для 409 — запропонувати «Це ваш пристрій?» з кнопкою звернення в підтримку. Інакше користувачі з купленими вживаними пристроями опиняться в глухому куті.
Що входить у роботу та терміни
Ми реалізуємо додавання IoT-пристрою за серійним номером під ключ. У результаті ви отримуєте:
- Вихідний код на Kotlin (Android) або Swift (iOS) з коментарями
- Інтеграцію з вашим REST API (специфікація, тестові запити)
- Документацію за форматами та обробкою помилок
- Тестування на реальних пристроях (до 5 моделей)
- Підтримку протягом 30 днів після здачі
Базова реалізація займає від 1 до 2 тижнів. Вартість розраховується індивідуально. Замовте реалізацію цієї функціональності під ключ — зв'яжіться з нами для оцінки вашого проєкту. Ми гарантуємо прозорий супровід та якісний код, перевірений на 10+ IoT-проєктах. Отримайте консультацію щодо вашого IoT-проєкту.







