Інтеграція Nearby Interaction (Apple UWB) у iOS-додаток
Nearby Interaction — фреймворк Apple для визначення точної дистанції та напрямку до іншого iPhone або аксесуара з чипом U1/U2. Це не Bluetooth proximity, не iBeacon та не GPS. UWB (Ultra Wideband) працює на сантиметровій точності: додаток отримує distance у метрах з точністю ±10–15 см та direction — 3D-вектор до пристрою у просторі (на iPhone 14 Pro+ через двунаправлені антени).
Використовується для: точного наведення у шеринзі файлів та платежах, знаходження загублених предметів (як AirTag), управління умним домом з прив'язкою до простору, AR-додатків з реальною просторовою прив'язкою.
Обмеження, які потрібно знати до старту
Тільки iPhone 11 та новіше. Чип U1 вперше з'явився у iPhone 11. iPhone SE (усі покоління) — без UWB. iPad — без UWB (крім спеціалізованих конфігурацій). Додаток обов'язково повинен перевіряти NISession.deviceCapabilities.supportsPreciseDistanceMeasurement.
Лише на переднему плані. NISession працює лише коли додаток на переднему плані. Без винятків. Якщо потрібно вимірювання у фоні — UWB не підходить, це апаратне обмеження.
Два пристрої, одна сесія. Для P2P-вимірювання обидва пристрої повинні створити NISession та обміняти NIDiscoveryToken. Токен неможна передати заздалегідь — він генерується при створенні сесії та змінюється при кожному перезапуску. Обмін токенами відбувається через MultipeerConnectivity, Bluetooth, сервер — на вашу вибір.
Як влаштована сесія
import NearbyInteraction
import MultipeerConnectivity
class UWBSessionManager: NSObject, NISessionDelegate {
private var niSession = NISession()
private var peerToken: NIDiscoveryToken?
override init() {
super.init()
niSession.delegate = self
}
func startSession(with peerToken: NIDiscoveryToken) {
let config = NINearbyPeerConfiguration(peerToken: peerToken)
config.isCameraAssistanceEnabled = true // Camera Assistance на iPhone 14 Pro+
niSession.run(config)
}
func session(_ session: NISession,
didUpdate nearbyObjects: [NINearbyObject]) {
guard let peer = nearbyObjects.first else { return }
if let distance = peer.distance {
print("Distance: \(distance) m")
}
if let direction = peer.direction {
print("Direction: \(direction)") // simd_float3
}
}
func session(_ session: NISession,
didInvalidateWith error: Error) {
// NIErrorCode.userDidNotAllow, .resourceUsageLimitReached, .sessionFailed
// при .resourceUsageLimitReached — просто перезапустити сесію
}
}
Обмін токенами через MultipeerConnectivity
Найпоширеніший підхід для P2P: використовуємо MCSession для передачі токена, а потім запускаємо NISession. Важливо: NIDiscoveryToken неможна передати як рядок — він Codable, кодуємо через NSKeyedArchiver:
let tokenData = try NSKeyedArchiver.archivedData(
withRootObject: niSession.discoveryToken!,
requiringSecureCoding: true
)
mcSession.send(tokenData, toPeers: peers, with: .reliable)
На приймаючій стороні:
let token = try NSKeyedUnarchiver.unarchivedObject(
ofClass: NIDiscoveryToken.self,
from: data
)
Спроба передати токен через JSON-кодування — не працює, NIDiscoveryToken не Encodable у стандартному смислі.
Camera Assistance
На iPhone 14 Pro та 15 серії доступний режим isCameraAssistanceEnabled = true. При цьому система показує нативний AR overlay поверх камери, допомагаючи наводитися на пристрій. Користувач бачить стрілку-указник. Активується лише якщо користувач дав дозвіл на камеру. Додає задержку ~200 мс до отримання перших direction-даних.
Що входить у роботу
- Перевірка сумісності пристрою (
NIDeviceCapability) - Настройка
NISessionз конфігурацією для P2P або аксесуарів (NINearbyAccessoryConfiguration) - Механізм обміну
NIDiscoveryToken(через MultipeerConnectivity, Bluetooth або REST) - Обробка оновлень дистанції/напрямку у реальному часі
- Camera Assistance overlay
- Обробка помилок та перезапуск сесії
- Тестування на двох фізичних пристроях (симулятор UWB не підтримує)
Терміни
5 днів. Тестування вимагає двох реальних iPhone з U1/U2 — симулятор недостатній. Вартість розраховується індивідуально після аналізу сценарію використання.







