Разработка
Как использовать CoreMotion для получения сенсорных данных
В этой статье мы разберемся, как он работает, и создадим простой интерфейс для отображения собранных данных.
Вдохновленный Swift Student Challenge 2023 и моим желанием попробовать что-то новое, я бросил вызов себе и решил изучить фреймворк, который я никогда раньше не использовал — CoreMotion.
В этой статье мы разберемся, как он работает, и создадим простой интерфейс для отображения собранных данных.
Что такое CoreMotion
CoreMotion — это фреймворк Apple, который передает информацию о движении и окружающей среде от бортовых датчиков устройства. Он, в частности, позволяет разработчикам получать доступ к данным о движении устройства, таким как ускорение, скорость и ориентация.
Кроме того, он оптимизирован для получения точных данных о движении даже в сложных условиях, таких как быстрое движение или изменение направления, поскольку использует датчики устройства для измерения и отслеживания движения в режиме реального времени.
Вы можете использовать этот фреймворк для доступа к данным, генерируемым оборудованием, и использовать их для всего, что только можно себе представить. Например, игра может использовать данные акселерометра и гироскопа для управления поведением игры на экране.
Погружение в CoreMotion
Пользователи генерируют события движения, когда двигают, трясут или наклоняют устройство. Эти события движения обнаруживаются аппаратным обеспечением устройства, и фреймворк позволяет вашему приложению получать и обрабатывать данные о движении.
Каждое устройство Apple имеет встроенное оборудование, которое можно использовать для сбора интересных данных. Давайте рассмотрим три основных компонента фреймворка CoreMotion:
- Акселерометр: Измеряет ускорение устройства и используется для обнаружения изменений в скорости и направлении движения
- Гироскоп: Измеряет угловую скорость устройства и используется для обнаружения изменений в ориентации и вращении.
- Магнитометр: Измеряет магнитное поле устройства и используется для определения ориентации устройства относительно магнитного поля Земли.
Существуют и другие типы датчиков, такие как барометры, шагомеры и датчики приближения, которые также хорошо задокументированы и информацию о них вы можете найти здесь.
Прежде чем мы сможем прочитать данные от этих датчиков, нам нужно глубоко погрузиться в то, как они представляются. Во-первых, важно понимать, что все значения, записываемые фреймворком устройства, относятся к референсной системе координат.
Это трехмерная система координат с тремя осями. Ось Z всегда направлена вниз по направлению силы тяжести (центр Земли), а направление оси X может быть определено вами при настройке менеджера движения. Наконец, ось Y перпендикулярна осям X и Z, завершая трехмерную систему координат.
Направление оси Y можно определить по правилу правой руки: если вы направляете большой палец в направлении оси X, а указательный палец — в направлении оси Z, то средний палец указывает в направлении оси Y.
Итак, чтобы лучше понять основные датчики и то, как они помогают отслеживать движение, мы можем взглянуть на то, что они могут измерять в своих трех координатах:
- Ускорение пользователя — ускорение, которое пользователь придает устройству
- Гравитация — ускорение под действием силы тяжести
- Скорость вращения — как пользователь вращает смартфон
Как использовать
В этой статье мы будем использовать SwiftUI и архитектуру MVVM.
Сначала вам нужно создать представление для отображения данных, которые вы будете получать. Вы можете спроектировать его как угодно, или посмотреть исходный код того, который я создал, здесь.
Теперь перейдем к собственно логике. Первое, что вам нужно сделать, это импортировать CoreMotion и создать экземпляр CMMotionManager. Кроме того, вам понадобятся некоторые свойства для хранения полученных значений.
class HomeViewModel: ObservableObject {
@Published var accelerationValue: String = ""
@Published var gravityValue: String = ""
@Published var rotationValue: String = ""
// The instance of CMMotionManager responsible for handling sensor updates
private let motionManager = CMMotionManager()
// Properties to hold the sensor values
private var userAcceleration: CMAcceleration = CMAcceleration()
private var gravity: CMAcceleration = CMAcceleration()
private var rotationRate: CMRotationRate = CMRotationRate()
}
Затем нам нужно получить фактические данные, которые мы получаем от датчиков. Поэтому мы создадим private функцию, которая будет проверять, доступны ли они, а затем начнет обновлять их, вызывая соответствующие методы.
private func startFetchingSensorData() {
// Check if the motion manager is available and the sensors are available
if motionManager.isDeviceMotionAvailable && motionManager.isAccelerometerAvailable && motionManager.isGyroAvailable {
// Start updating the sensor data
motionManager.startDeviceMotionUpdates(to: .main) { [weak self] (motion, error) in
guard let self = self else { return } // Avoid memory leaks
// Check if there's any error in the sensor update
if let error = error {
print("Error: \(error.localizedDescription)")
}
getMotionAndGravity(motion: motion)
}
motionManager.startGyroUpdates(to: .main) { [weak self] (gyroData, error) in
guard let self = self else { return }
getRotation(gyroData: gyroData)
}
}
}
Далее нам останется только создать методы, которые будут извлекать значения ускорения, гравитации и вращения, и сделать так, чтобы они обновляли соответствующие @Published свойства, чтобы они могли публиковать изменения подписчикам нашего представления.
private func getMotionAndGravity(motion: CMDeviceMotion?){
if let motion = motion {
// Get user acceleration and gravity data
self.userAcceleration = motion.userAcceleration
self.gravity = motion.gravity
// Update publishers with the new sensor data
self.accelerationValue = "X: \(userAcceleration.x), \n Y: \(userAcceleration.y), \n Z: \(userAcceleration.z)"
self.gravityValue = "X: \(gravity.x), \n Y: \(gravity.y), \n Z: \(gravity.z)"
}
}
private func getRotation(gyroData: CMGyroData?){
if let gyroData = gyroData {
// Get rotation rate data
self.rotationRate = gyroData.rotationRate
// Update publisher with the new sensor data
self.rotationValue = "X: \(rotationRate.x), \n Y: \(rotationRate.y), \n Z: \(rotationRate.z)"
}
}
После этого вы можете начать перемещаться и вращать свое устройство, чтобы увидеть обновление данных в режиме реального времени! Я призываю вас начать исследовать возможности взаимодействия на основе движения в ваших собственных проектах.
Заключение
CoreMotion — это мощный фреймворк, открывающий бесчисленные возможности для использования движений. Он полезен не только для разработчиков, но и для пользователей, которые могут извлечь пользу из нового и уникального опыта.
Я использовал его для создания своего проекта-победителя WWDC 23, Space Cruiser! 🏆
Логика игры предполагает управление космическим кораблем, а движение устройства используется для управления его перемещением. Космический корабль управляется с помощью наклона устройства, что добавляет игре новый уровень погружения.
Space Cruiser доступен на GitHub, как и исходный код для этой статьи.
-
Аналитика магазинов2 недели назад
Мобильный рынок Ближнего Востока: исследование Bidease и Sensor Tower выявляет драйверы роста
-
Интегрированные среды разработки3 недели назад
Chad: The Brainrot IDE — дикая среда разработки с играми и развлечениями
-
Новости4 недели назад
Видео и подкасты о мобильной разработке 2025.45
-
Новости3 недели назад
Видео и подкасты о мобильной разработке 2025.46




