Мы собрали 20 лет заметок о световой живописи в один гид. Он бесплатный. Читать гид ×
× ПриложенияТехнологииГалерея БлогО студииНаписать нам ›
Главная/Блог/Core Motion и сенсоры iPhone: как использовать акселерометр в приложении
Технологии

Core Motion и сенсоры iPhone: как использовать акселерометр в приложении

Андрей Морозов · 2026-10-19

Акселерометр, гироскоп и магнетометр iPhone дают приложению ощущение движения и наклона — но доступ к ним устроен не так просто, как кажется: сырые данные с датчиков и «умный» device motion решают разные задачи. В студии oodot мы используем Core Motion в Glow Doodle и Light Painting для жестов, наклона кисти и калибровки движения — и при разработке мобильных приложений под ключ эта работа с датчиками часто становится ядром пользовательского опыта. В этой статье разберём, чем отличаются классы Core Motion, как запустить обновления акселерометра на Swift и как выбрать частоту без разряда батареи.

Коротко: Core Motion — фреймворк Apple для работы с сенсорами движения iPhone через CMMotionManager. Он отдаёт три вида данных: сырой акселерометр (CMAccelerometerData), сырой гироскоп (CMGyroData) и объединённый device motion (CMDeviceMotion) с отфильтрованными gravity и userAcceleration. Для большинства задач — наклон, тряска, жесты — нужен именно device motion, а не сырые данные.
iPhone в руке разработчика с визуализацией данных акселерометра

Что такое Core Motion и зачем он нужен приложению

Core Motion — системный фреймворк iOS, который собирает данные со всех датчиков движения iPhone: акселерометра, гироскопа, магнетометра и барометра — и отдаёт их приложению через единый API. Центральный объект здесь — CMMotionManager: он включает нужные сенсоры, задаёт частоту опроса и присылает замеры в обработчик (handler) на каждый цикл обновления.

На практике Core Motion используют для вещей, которые не решить без физических датчиков: shake-жесты (встряхнуть телефон для отмены действия), наклон экрана для управления интерфейсом, подсчёт шагов через CMPedometer, определение высоты через CMAltimeter, распознавание активности пользователя (ходьба, бег, в машине) через CMMotionActivityManager. Это и есть тот слой, который превращает iPhone из экрана с кнопками в устройство, реагирующее на движение в руке.

Для нашей студии это не абстрактная теория: когда в проекте нужна разработка мобильного приложения под ключ с жестовым управлением или интеграцией с датчиками, Core Motion почти всегда оказывается в основе технического решения — именно он даёт доступ к сырым и обработанным данным движения, без которых творческие механики (световая живопись, наклон кисти, калибровка жеста) просто не собрать.

Чем accelerometer отличается от gyroscope и deviceMotion?

Это три разных источника данных в Core Motion, и путаница между ними — частая причина багов в движении интерфейса. Разберём каждый.

CMAccelerometerData — сырое линейное ускорение

Акселерометр измеряет линейное ускорение вдоль трёх осей (x, y, z) в единицах g (гравитационное ускорение Земли). Данные в CMAccelerometerData сырые — они включают и ускорение от движения руки, и постоянную составляющую гравитации. Отделить одно от другого самостоятельно — отдельная задача фильтрации.

CMGyroData — угловая скорость (вращение)

Гироскоп измеряет угловую скорость вращения вокруг тех же трёх осей, в радианах в секунду. Он отвечает не «куда наклонился телефон», а «как быстро он сейчас вращается» — это другая физическая величина, и сама по себе она не даёт абсолютной ориентации устройства.

CMDeviceMotion — объединённые, отфильтрованные данные

CMDeviceMotion — это результат сенсорного фьюжна: система объединяет показания акселерометра, гироскопа и (при доступности) магнетометра и отдаёт уже разделённые gravity (вектор силы тяжести) и userAcceleration (ускорение именно от движения руки, без гравитации), а также ориентацию устройства в виде кватерниона. Для большинства прикладных задач — наклон, тряска, жесты — нужен именно этот объект, а не сырые данные акселерометра.

СенсорЧто измеряетКласс Core MotionТипичный кейс
АкселерометрЛинейное ускорение (движение + гравитация)CMAccelerometerDataShake-жест, грубое определение тряски
ГироскопУгловая скорость вращенияCMGyroDataПлавность вращения, стабилизация кадра
Device MotionGravity + userAcceleration + ориентацияCMDeviceMotionНаклон интерфейса, жесты рисования, AR
МагнетометрМагнитное поле (компас)CMMagnetometerDataНаправление, азимут, компас-режимы

Разрешения и Info.plist

Хорошая новость: базовый доступ к акселерометру, гироскопу и device motion не требует запроса разрешения у пользователя и записи в Info.plist — Apple считает эти данные не настолько чувствительными, как геолокация или камера. Ключ NSMotionUsageDescription нужен только для более «личных» данных движения — CMMotionActivityManager (распознавание активности: ходьба, бег, транспорт) и CMPedometer (история шагов). Без этого ключа запрос на активность и шагомер завершится ошибкой, а не крашем — проверяйте это явно в коде, если используете эти API.

Запуск обновлений акселерометра — код на Swift

Базовый сценарий — создать CMMotionManager, задать частоту опроса и запустить обновления с обработчиком на отдельной очереди.

import CoreMotion

final class MotionViewModel: ObservableObject {
    private let motionManager = CMMotionManager()
    private let motionQueue = OperationQueue()

    @Published var acceleration: CMAcceleration?

    func startAccelerometerUpdates() {
        guard motionManager.isAccelerometerAvailable else { return }

        motionManager.accelerometerUpdateInterval = 1.0 / 60.0 // 60 Hz

        motionManager.startAccelerometerUpdates(to: motionQueue) { [weak self] data, error in
            guard let self, let data, error == nil else { return }

            DispatchQueue.main.async {
                self.acceleration = data.acceleration
            }
        }
    }

    func stopAccelerometerUpdates() {
        motionManager.stopAccelerometerUpdates()
    }
}

Обратите внимание: обработчик startAccelerometerUpdates(to:) вызывается на очереди, которую вы передали, а не на главном потоке — любое обновление UI нужно явно переносить через DispatchQueue.main.async, как в примере выше.

deviceMotion vs raw accelerometer — когда что использовать?

Если нужно просто отреагировать на резкий толчок (shake-to-undo) — хватит сырого акселерометра и простой проверки порога ускорения. Но если задача — наклон интерфейса, рисование жестом или любая механика, где важна именно ориентация устройства без шума от руки, — используйте CMDeviceMotion:

func startDeviceMotionUpdates() {
    guard motionManager.isDeviceMotionAvailable else { return }

    motionManager.deviceMotionUpdateInterval = 1.0 / 60.0
    motionManager.startDeviceMotionUpdates(to: motionQueue) { [weak self] motion, error in
        guard let self, let motion, error == nil else { return }

        let gravity = motion.gravity            // вектор силы тяжести
        let userAccel = motion.userAcceleration // ускорение без гравитации

        DispatchQueue.main.async {
            self.handleTilt(gravity: gravity, userMotion: userAccel)
        }
    }
}

Разница на практике: сырой CMAccelerometerData.acceleration всегда содержит примесь гравитации — телефон, лежащий неподвижно экраном вверх, уже покажет ускорение около 1g по оси z. userAcceleration в device motion эту составляющую уже вычел, поэтому в состоянии покоя значения близки к нулю. Если ваша логика реагирует на «движение руки», а не на «положение телефона», берите userAcceleration, а не сырые данные.

Частота обновления и энергопотребление

Частота обновления (updateInterval) напрямую влияет на расход батареи: чем выше частота опроса датчиков, тем чаще система будит ядро обработки движения и будит ваш обработчик на CPU. Для большинства UI-задач — наклон, параллакс, индикаторы — достаточно 30–60 Hz; для точной рисовательной механики или анализа жеста (как в Glow Doodle) имеет смысл поднимать до 60–100 Hz, но не выше, если приложение не делает precision-трекинг для AR или спортивной аналитики.

Практическое правило: запускайте обновления датчиков только тогда, когда экран, которому они нужны, активен, и обязательно останавливайте через stop...Updates() при уходе с экрана или в фон. Постоянно работающий Core Motion на фоне — одна из частых причин жалоб на разряд батареи в отзывах на App Store, и это полностью на совести реализации, а не системы.

Практика: акселерометр в творческом приложении

В студии oodot сенсоры движения — не демо-функция, а часть основной механики продукта. Несколько примеров того, как это работает на уровне кода и UX:

Shake-to-undo. Простейший паттерн: слушаем userAcceleration из device motion, считаем магнитуду вектора (sqrt(x² + y² + z²)) и сравниваем с порогом (обычно 2.0–2.5g суммарной амплитуды за короткое окно). Превышение порога — триггер отмены последнего действия.

Наклон для управления светом или кистью. В световой живописи наклон телефона — это естественный аналог наклона реальной кисти. Берём gravity из device motion (он стабильнее сырого акселерометра, потому что уже отфильтрован от шума движения руки) и мапим угол наклона на толщину линии, яркость или цвет мазка.

Калибровка под жест. Перед началом сессии рисования полезно зафиксировать «нулевое» положение телефона в руке пользователя (у всех разный хват) и дальше считать наклон относительно этой калибровочной точки, а не абсолютной оси устройства — иначе приложение будет «неправильно» реагировать на естественный наклон в руке у разных людей.

Частые ошибки при работе с Core Motion

Несколько вещей, которые ломают приложения с датчиками даже у опытных разработчиков:

Не останавливать обновления. Забытый вызов stopAccelerometerUpdates() или stopDeviceMotionUpdates() при переходе на другой экран держит датчики активными впустую — это прямой расход батареи без пользы.

Не проверять доступность сенсора. Не на всех устройствах (и в Simulator) доступны все датчики — обязательно проверяйте isAccelerometerAvailable / isDeviceMotionAvailable перед стартом, иначе обработчик просто никогда не вызовется, и вы потратите время на поиск несуществующего бага.

Блокировать главный поток. Обработка данных движения (фильтрация, математика, обновление сложного UI) в обработчике обновлений не должна выполняться синхронно на главном потоке — переносите тяжёлые вычисления на фоновую очередь и возвращайтесь на DispatchQueue.main только для финального обновления интерфейса.

FAQ: частые вопросы про Core Motion и акселерометр iPhone

Нужно ли разрешение пользователя для доступа к акселерометру?

Нет — базовый доступ к акселерометру, гироскопу и device motion не требует системного запроса разрешения и записи в Info.plist. Разрешение (и ключ NSMotionUsageDescription) нужны только для распознавания активности (CMMotionActivityManager) и истории шагов (CMPedometer).

Какую частоту обновления выбрать для акселерометра?

Для UI-эффектов (наклон, параллакс) достаточно 30–60 Hz. Для точной рисовательной механики или жестового управления — 60–100 Hz. Выше без явной необходимости — лишний расход батареи, не дающий заметного прироста качества для большинства задач.

Чем CMDeviceMotion лучше сырого CMAccelerometerData?

CMDeviceMotion — результат сенсорного фьюжна акселерометра, гироскопа и магнетометра: он отдаёт уже разделённые gravity и userAcceleration, а сырой акселерометр всегда содержит примесь гравитации, которую нужно вычислять вручную.

Можно ли использовать Core Motion в iOS Simulator?

Частично. Device Motion и акселерометр в Simulator можно эмулировать через меню Features → симуляцию движения, но это упрощённые синтетические данные. Для реальной проверки чувствительности и качества жестов нужен физический iPhone.

Как определить, что iPhone лежит неподвижно?

Проверяйте userAcceleration из device motion — в покое все три оси близки к нулю (гравитация уже вычтена). Сырой акселерометр для этой задачи не подходит: в покое он всё равно показывает около 1g за счёт гравитации.

Почему данные акселерометра «дёргаются» и шумят?

Сырой акселерометр физически чувствителен к микровибрациям руки и окружения. Для сглаживания применяют низкочастотный фильтр (например, скользящее среднее) или используют CMDeviceMotion, где часть фильтрации уже выполнена системой на уровне сенсорного фьюжна.

Можно ли получать данные с акселерометра в фоновом режиме?

Обновления Core Motion останавливаются, когда приложение уходит в фон без специальных entitlement (например, для фитнес-трекеров). Для большинства творческих приложений это ожидаемое поведение — останавливайте обновления сами при переходе в фон, не дожидаясь системного прерывания.

Core Motion — один из тех фреймворков Apple, которые незаметны, пока работают правильно: пользователь просто чувствует, что приложение реагирует на движение естественно. Разница между CMAccelerometerData, CMGyroData и CMDeviceMotion, разумная частота обновления и аккуратная остановка сенсоров — три вещи, которые отделяют рабочую механику от разряженной батареи и дёрганого UI. Для нашей студии это рабочий инструмент в каждом проекте, где движение телефона становится частью интерфейса.

Есть вопрос по теме?

Напишите нам — с удовольствием разберём ваш случай и, может быть, сделаем из него следующую статью.

xdt_software@oodot.com ›