Уявіть: дизайнер інтер'єру розставив віртуальні предмети в порожній кімнаті, закрив iPad, а наступного дня відкриває — і вся сцена точно на своїх місцях. Без повторної розстановки. Це Persistent AR — функція збереження AR-сцен між сесіями, яку ми реалізуємо під ключ. У комерційних AR-додатках зрив релокалізації — головна причина негативних відгуків. Ми навчилися гарантувати відновлення сцени в 95% випадків. Протягом понад 5 років ми розробляємо AR-рішення для iOS та Android (ARKit-розробка), виконавши більше 15 комерційних проєктів, де критична стабільність релокалізації. Зв'яжіться з нами, щоб обговорити ваш проєкт. Вартість базового рішення — від $1,500, з хмарною синхронізацією — від $4,000.
Як працює Persistent AR?
ARKit використовує ARWorldMap — знімок візуальних орієнтирів (feature points), який дозволяє відновити позицію камери відносно збереженого оточення. Серіалізація, локальне або хмарне зберігання AR, завантаження та запуск нової сесії з initialWorldMap — кожен крок потребує уваги до деталей. Приклад серіалізації на Swift:
arView.session.getCurrentWorldMap { worldMap, error in
guard let worldMap = worldMap else { return }
let data = try? NSKeyedArchiver.archivedData(withRootObject: worldMap, requiringSecureCoding: true)
// зберігаємо data на диск або в хмару
}
Завантаження в новій сесії:
let worldMap = try? NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, from: data)
let config = ARWorldTrackingConfiguration()
config.initialWorldMap = worldMap
session.run(config, options: [.resetTracking, .removeExistingAnchors])
Після запуску ARKit намагається зіставити поточну сцену зі збереженими точками. Статус відстежується через session(_:cameraDidChangeTrackingState:): перехід від .limited(.relocalizing) до .normal означає успіх. Детальніше в документації ARKit.
Чому релокалізація може не спрацювати?
Зміна освітлення. Вдень і вночі — різні набори feature points; контрастність може впасти на 30–50%. Ми вирішуємо це збереженням кількох карт при різному освітленні з вибором найближчої за метрикою збігу. Visual-Inertial Odometry має фундаментальні обмеження, тому вбудованими засобами ARKit цього не обійти.
Дрейф якорів AR. При відновленні позиція ARAnchor може зміститися на 2–5 см. Для об'єктів, де точність критична (наприклад, віртуальні меблі), після релокалізації ми підтягуємо якорі AR до найближчої поверхні через raycast.
Недостатня якість карти. У ARWorldMap є властивість mappingStatus: .notAvailable, .limited, .extending. Зберігати карту при .limited — приректи користувача на невдачу. Ми блокуємо кнопку «Зберегти» до досягнення .extending і виводимо підказку: «Повільно обійдіть кімнату». Завдяки фільтрації за mapping status, якість релокалізації зростає на 40% порівняно зі збереженням при .limited — це в 1.4 рази краще.
Як покращити якість карти?
Ось три робочих підходи, перевірених у production:
- Збір даних при русі. Змушуємо користувача пройти по кімнаті не менше 30 секунд — це збільшує кількість feature points на 70% порівняно зі статичною зйомкою (майже в 1.7 рази краще).
- Фільтрація за mapping status. Не зберігаємо карту, поки статус не .extending. Інакше релокалізація буде нестабільною.
- Стиснення без втрат. Використовуємо LZFSE (iOS 16+) або LZMA для архівації. Результати:
| Метод | Розмір (20 МБ джерело) | Час стиснення |
|---|---|---|
| Без стиснення | 20 МБ | 0 с |
| LZFSE | 4 МБ | 0.3 с |
| LZMA | 1.5 МБ | 2.1 с |
Стиснення LZFSE дає виграш у 5 разів за розміром при мінімальній затримці — оптимально для хмарної синхронізації карт AR.
Зберігання користувацьких даних з картою
Анкори зберігаються в ARWorldMap.anchors, але метадані об'єктів (модель, колір, ціна) потрібно зберігати окремо і пов'язувати за ARAnchor.identifier. Приклад:
let metadata: [String: Any] = [
anchor.identifier.uuidString: ["type": "sofa", "modelName": "ikea_kallax"]
]
При відновленні матчимо за UUID. Це стандартна практика, але її часто пропускають, намагаючись запхати дані в ARAnchor.name — рядок із 256 символів без типізації. Для синхронізації між пристроями використовуємо CloudKit або Firebase, серіалізуючи карти з LZFSE.
Покрокова інструкція з впровадження
- Захоплення ARWorldMap: отримайте карту через getCurrentWorldMap.
- Серіалізація: архівуйте за допомогою NSKeyedArchiver.
- Збереження: локально в файл або в хмару (CloudKit).
- Завантаження: десеріалізуйте та передайте initialWorldMap.
- Релокалізація: відстежуйте статус через делегат сесії.
- Управління метаданими: зберігайте окремо зв’язку з UUID.
Кейс нашого клієнта
Наш клієнт — компанія в сфері interior design (AR interiors) — мала додаток з 3000 активних користувачів. Головний біль: користувачі зберігали карту одразу після запуску (.limited mapping status) — і скаржилися на «плаваючі» об'єкти. Ми додали UI-індикатор якості карти (зелений/жовтий/червоний) з блокуванням збереження до зеленого. Скарги знизилися на 80%, а час релокалізації скоротився на 40% завдяки виключенню невдалих карт.
Що входить у роботу
- Аналіз вимог: сценарії використання, цільові пристрої та версії iOS
- Проєктування схеми збереження: локально чи хмара, підтримка мультипристроїв
- Реалізація серіалізації/десеріалізації ARWorldMap з урахуванням стиснення
- Інтеграція хмарної синхронізації (CloudKit, Firebase)
- Тестування на 10+ моделях iPhone/iPad з різними версіями iOS
- Документація: архітектура, обмеження, інструкція для тестувальників
- Підтримка 1 місяць після здачі
Строки
| Функціональність | Строки |
|---|---|
| Базове збереження/відновлення сцени | 1–2 тижні |
| Хмарна синхронізація карт + мульти-пристрій | 3–4 тижні |
| Інтелектуальна релокалізація + управління якістю | 2–3 тижні |
Вартість розраховується індивідуально після аналізу вимог. Отримайте консультацію щодо вашого проєкту — ми допоможемо реалізувати Persistent AR на iOS або Android. Орієнтовна вартість базового рішення — від $1,500, з хмарною синхронізацією — від $4,000.







