iOS开发之CoreMotion框架的应用

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: iOS开发之CoreMotion框架的应用

iOS开发之CoreMotion框架的应用


     我们知道,现在智能手机手机的功能已经越来越强大。小小的手机中集成了众多的传感器配件。通过这些传感器可以获取到手机甚至用户的状态信息。


     在iOS5之前,加速度传感器的相关信息封装在UIAccelerometer这个类中,其主要用来获取设备在三维空间中的状态信息,之后,加速度传感器以及螺旋仪传感器的相关信息都封装在了CoreMotion这个框架中,这个框架对加速度,磁力以及螺旋仪传感器信息进行统一管理,并封装了许多强大的计算方法帮助开发者获取设备的空间状态。


     之前有写过一篇关于UIAccelerometer与CoreMotion简单使用的博客,比较偏用法介绍,并不系统,本篇博客是针对CoreMotion的完善与补充。


https://my.oschina.net/u/2340880/blog/543434


一、CoreMotion框架整体结构


   在学习这个框架之前,首先需要对框架中类的关系与作用有个整体的了解。下图展示了CoreMotion框架的整体结构:


image.png


从上图中可以看出,CoreMotion框架中主要分为3大块,一部分是用来获取设备的运动状态,如速度,加速度,海拔,三维方向等。一部分是用来配合iWatch进行用户的运动状态获取、另一部分为用户步数相关接口。


二、CMMotionManager


     CMMotionManager类是CoreMotion框架中非常核心的一个类,其用来进行设备运动信息的整体管理。主要包括开启更新信息,停止更新信息,获取更新信息等。解析如下:


//获取加速计是否可用

@property(readonly, nonatomic, getter=isAccelerometerAvailable) BOOL accelerometerAvailable;

//加速计更新间隔

@property(assign, nonatomic) NSTimeInterval accelerometerUpdateInterval;

//加速计是否在持续进行更新

@property(readonly, nonatomic, getter=isAccelerometerActive) BOOL accelerometerActive;

//最后一次更新的加速计信息  CMAccelerometerData后面会介绍

@property(readonly, nullable) CMAccelerometerData *accelerometerData;

//开始进行加速计数据更新

- (void)startAccelerometerUpdates;

//开始进行加速计数据更新 并且指定回调函数以及回调函数执行的线程

- (void)startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMAccelerometerHandler)handler;

//停止加速计数据的更新

- (void)stopAccelerometerUpdates;

//陀螺仪是否可用

@property(readonly, nonatomic, getter=isGyroAvailable) BOOL gyroAvailable;

//陀螺仪数据的更新间隔

@property(assign, nonatomic) NSTimeInterval gyroUpdateInterval;

//陀螺仪是否在持续进行更新

@property(readonly, nonatomic, getter=isGyroActive) BOOL gyroActive;

//陀螺仪数据

@property(readonly, nullable) CMGyroData *gyroData;

//开启陀螺仪的更新

- (void)startGyroUpdates;

//开始进行陀螺仪的更新 并且指定回调函数以及回调函数执行的线程

- (void)startGyroUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMGyroHandler)handler;

//停止进行陀螺仪数据的更新

- (void)stopGyroUpdates;

//磁力计是否可用

@property(readonly, nonatomic, getter=isMagnetometerAvailable) BOOL magnetometerAvailable;

//磁力计数据更新间隔

@property(assign, nonatomic) NSTimeInterval magnetometerUpdateInterval;

//磁力计数据是否在持续更新

@property(readonly, nonatomic, getter=isMagnetometerActive) BOOL magnetometerActive;

//磁力计数据

@property(readonly, nullable) CMMagnetometerData *magnetometerData;

//开始更新磁力计数据

- (void)startMagnetometerUpdates;

//开始更新磁力计数据 并且指定回调函数以及回调函数执行的线程

- (void)startMagnetometerUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMMagnetometerHandler)handler;

//停止磁力计的更新

- (void)stopMagnetometerUpdates;


//设备运动数据并非某个传感器的数据 而是上面3种传感器数据的组合与运算

//设备运动数据是否可用

@property(readonly, nonatomic, getter=isDeviceMotionAvailable) BOOL deviceMotionAvailable;

//设备运动数据更新间隔

@property(assign, nonatomic) NSTimeInterval deviceMotionUpdateInterval;

//是否在持续更新设备运动数据

@property(readonly, nonatomic, getter=isDeviceMotionActive) BOOL deviceMotionActive;

//最后一次更新的设备运动信息数据

@property(readonly, nullable) CMDeviceMotion *deviceMotion;

//开始更新设备运动数据

- (void)startDeviceMotionUpdates;

//开始更新设备运动数据 并指定回调函数以及回调函数执行的线程

- (void)startDeviceMotionUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMDeviceMotionHandler)handler;

//停止更新设备运动信息

- (void)stopDeviceMotionUpdates;

上面的方法看上去非常繁多,其实很有规律,总的来说就是对是否开启传感器数据进行管理,并且进行传感器数据的获取。下面我们来看几种具体的传感器数据类的定义。


三、数据模型类


     首先,CoreMotion框架中的数据模型类都继承自CMLogItem类,这个类里面只有一个属性:


@interface CMLogItem : NSObject <NSSecureCoding, NSCopying>

@property(readonly, nonatomic) NSTimeInterval timestamp;

@end

CMLogItem类的timestamp属性用来标记数据记录的时间戳。


1.加速计数据


     CMAccelerometerData是加速计数据的数据模型类:


@interface CMAccelerometerData : CMLogItem

//加速计数据

@property(readonly, nonatomic) CMAcceleration acceleration;

@end

//加速计数据结构体

typedef struct {

double x;   //x方向加速度

double y;   //y方向加速度

double z;   //z方向加速度

} CMAcceleration;

2、陀螺仪数据


     CMGyroData是陀螺仪数据的数据模型类:


@interface CMGyroData : CMLogItem

//角速度数据

@property(readonly, nonatomic) CMRotationRate rotationRate;

@end


//角速度结构体

typedef struct {

double x;  //x方向的角速度

double y;  //y方向的角速度

double z;  //z方向的角速度

} CMRotationRate;

3.磁强计数据


     CMMagnetometerData是磁强计数据模型类:


@interface CMMagnetometerData : CMLogItem

{

//磁强数据

@property(readonly, nonatomic) CMMagneticField magneticField;


@end


typedef struct {

   double x;   //x轴磁场

   double y;   //y轴磁场

   double z;   //z轴磁场

} CMMagneticField;

4.设备运动信息


     CMDeviceMotion类包含了设备的空间状态信息:


@interface CMDeviceMotion : CMLogItem

//设备的空间状态  CMAttitude后面会介绍

@property(readonly, nonatomic) CMAttitude *attitude;

//设备的 陀螺仪数据

@property(readonly, nonatomic) CMRotationRate rotationRate;

//设备的 加速计数据

@property(readonly, nonatomic) CMAcceleration gravity;

//获取用户给设备带来的加速度

@property(readonly, nonatomic) CMAcceleration userAcceleration;

//设备附近磁场相关信息

@property(readonly, nonatomic) CMCalibratedMagneticField magneticField;

//返回航向角度

@property(readonly, nonatomic) double heading;

@end

CMCalibratedMagneticField是一个结构体,如下:


typedef struct {

   CMMagneticField field;  //磁场

   CMMagneticFieldCalibrationAccuracy accuracy; //磁场强度

} CMCalibratedMagneticField;


typedef NS_ENUM(int, CMMagneticFieldCalibrationAccuracy) {

CMMagneticFieldCalibrationAccuracyUncalibrated = -1,

CMMagneticFieldCalibrationAccuracyLow, //低

CMMagneticFieldCalibrationAccuracyMedium,//中

CMMagneticFieldCalibrationAccuracyHigh//高

} ;

CMAttitude类中封装的信息如下:


@interface CMAttitude : NSObject <NSCopying, NSSecureCoding>

{

//设备翻滚弧度

@property(readonly, nonatomic) double roll;

//旋转弧度

@property(readonly, nonatomic) double pitch;

//航偏

@property(readonly, nonatomic) double yaw;

//描述设备状态的旋转矩阵

@property(readonly, nonatomic) CMRotationMatrix rotationMatrix;

//描述设备姿态的四元数

@property(readonly, nonatomic) CMQuaternion quaternion;

//进行转换

- (void)multiplyByInverseOfAttitude:(CMAttitude *)attitude;


@end

//四元数

typedef struct

{

double x, y, z, w;

} CMQuaternion;

//矩阵

typedef struct

{

double m11, m12, m13;

double m21, m22, m23;

double m31, m32, m33;

} CMRotationMatrix;

四、高度信息


    CoreMotion框架中的CMAltimeter类提供对设备高度相关信息的数据支持,这个类是iOS 8后新加入的,CMAltimeter类解析如下:


@interface CMAltimeter : NSObject

//是否支持相对高度变化

+ (BOOL)isRelativeAltitudeAvailable;

//进行用户权限的申请

+ (CMAuthorizationStatus)authorizationStatus;

//开始更新高度变化信息数据

- (void)startRelativeAltitudeUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMAltitudeHandler)handler;

//停止更新高度变化信息数据

- (void)stopRelativeAltitudeUpdates;

@end

CMAltitudeData是高度信息数据:


@interface CMAltitudeData : CMLogItem

//相对高度 单位为米

@property(readonly, nonatomic) NSNumber *relativeAltitude;

//压力 单位为千帕

@property(readonly, nonatomic) NSNumber *pressure;

@end

五、用户活动信息


     CMMotionActivityManager类是iOS 7之后新引入到CoreMotion框架中的,这个类用来对用户的活动信息进行管理,解析如下:


@interface CMMotionActivityManager : NSObject

//活动数据是否可用

+ (BOOL)isActivityAvailable;

//进行用户权限的申请

+ (CMAuthorizationStatus)authorizationStatus;

//请求某一段时间内的用户活动信息

- (void)queryActivityStartingFromDate:(NSDate *)start

                              toDate:(NSDate *)end

                             toQueue:(NSOperationQueue *)queue

                         withHandler:(CMMotionActivityQueryHandler)handler;

//开始进行用户活动信息的更新

- (void)startActivityUpdatesToQueue:(NSOperationQueue *)queue

                       withHandler:(CMMotionActivityHandler)handler;

//停止用户活动信息的更新

- (void)stopActivityUpdates;

@end

CMMotionActivity是用户活动信息的具体记录:


@interface CMMotionActivity : CMLogItem

//数据的可信度

/*

typedef NS_ENUM(NSInteger, CMMotionActivityConfidence) {

CMMotionActivityConfidenceLow = 0,  //可信度低

CMMotionActivityConfidenceMedium,   //可信度中

CMMotionActivityConfidenceHigh      //可信度高

};

*/

@property(readonly, nonatomic) CMMotionActivityConfidence confidence;

//记录开始时间

@property(readonly, nonatomic) NSDate *startDate;

//是否是位置状态 如果是 可能关机状态

@property(readonly, nonatomic) BOOL unknown;

//设备是否没有移动

@property(readonly, nonatomic) BOOL stationary;

//设备持有者是否在步行

@property(readonly, nonatomic) BOOL walking;

//设备持有者是否在跑步

@property(readonly, nonatomic) BOOL running;

//设备持有者是否在乘车

@property(readonly, nonatomic) BOOL automotive;

//设备持有者是否在骑自行车

@property(readonly, nonatomic) BOOL cycling;

@end

六、用户手臂动作分析


     在iOS 12系统后,CoreMotion框架中又引入了一些列配合iWatch进行用户手臂动作分析的类,可以分析出用户是否发生了运动障碍等。其主要由CMMovementDisorderManager类进行管理,如下:


@interface CMMovementDisorderManager : NSObject

//运动障碍管理类是否可用

+ (BOOL)isAvailable;

//进行用户权限的请求

+ (CMAuthorizationStatus)authorizationStatus;

//记录和计算一段时间内的震颤和运动异常结果

- (void)monitorKinesiasForDuration:(NSTimeInterval)duration;

//获取一段时间内的运动障碍记录数据

- (void)queryDyskineticSymptomFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate withHandler:(CMDyskineticSymptomResultHandler)handler;

//获取一段时间内的震颤记录数据

- (void)queryTremorFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate withHandler:(CMTremorResultHandler)handler;

//最后一次更新数据的时间

- (NSDate * _Nullable)lastProcessedDate;

//最后一次计算数据的过期时间

- (NSDate * _Nullable)monitorKinesiasExpirationDate;

@end

CMDyskineticSymptomResult运动障碍数据模型:


@interface CMDyskineticSymptomResult : NSObject <NSCopying, NSSecureCoding>

//记录数据的开始时间

@property (copy, nonatomic, readonly) NSDate *startDate;

//记录数据的结束时间

@property (copy, nonatomic, readonly) NSDate *endDate;

//运动异常可能出现的百分比

@property (nonatomic, readonly) float percentUnlikely;

//正常的百分比

@property (nonatomic, readonly) float percentLikely;

@end

CMTremorResult记录用户震颤数据:


@interface CMTremorResult : NSObject <NSCopying, NSSecureCoding>

//数据记录开始时间

@property (copy, nonatomic, readonly) NSDate *startDate;

//数据记录结束时间

@property (copy, nonatomic, readonly) NSDate *endDate;

//无法确定的时间百分比

@property (nonatomic, readonly) float percentUnknown;

//未检测到震颤的时间百分比

@property (nonatomic, readonly) float percentNone;

//可能发生震颤的百分比低 微震颤

@property (nonatomic, readonly) float percentSlight;

//可能发生震颤的百分比高 微震颤

@property (nonatomic, readonly) float percentMild;

//可能发生震颤的百分比高 中等震颤

@property (nonatomic, readonly) float percentModerate;

//可能发生震颤的百分比高 高震颤

@property (nonatomic, readonly) float percentStrong;

七、计步器应用


     在iOS 8之后,CoreMotion中引入了CMPedometer相关计步器类,这些类封装的更加应用层,开发者可以直接获取用户步数相关数据,CMPedometer是管理类,解析如下:


@interface CMPedometer : NSObject

//计步器是否可用

+ (BOOL)isStepCountingAvailable;

//距离检测是否可用

+ (BOOL)isDistanceAvailable;

//楼层检测是否可用

+ (BOOL)isFloorCountingAvailable;

//速度估算是否支持

+ (BOOL)isPaceAvailable;

//频率估算是否支持

+ (BOOL)isCadenceAvailable;

//计步器功能是否支持

+ (BOOL)isPedometerEventTrackingAvailable;

//进行用户权限申请

+ (CMAuthorizationStatus)authorizationStatus;

//请求一段时间的计步器数据

- (void)queryPedometerDataFromDate:(NSDate *)start

      toDate:(NSDate *)end

       withHandler:(CMPedometerHandler)handler;

//请求从某个时间至今的计步器数据

- (void)startPedometerUpdatesFromDate:(NSDate *)start

       withHandler:(CMPedometerHandler)handler;

//停止计步器数据更新

- (void)stopPedometerUpdates;

//开始更新计步器事件

- (void)startPedometerEventUpdatesWithHandler:(CMPedometerEventHandler)handler;

//停止更新计数器事件

- (void)stopPedometerEventUpdates;

@end

CMPedometerEvent类记录计步器的事件变化:


@interface CMPedometerEvent : NSObject <NSSecureCoding, NSCopying>

//记录数据的时间

@property(readonly, nonatomic) NSDate *date;

/*

typedef NS_ENUM(NSInteger, CMPedometerEventType) {

CMPedometerEventTypePause,   //计步器暂停

CMPedometerEventTypeResume   //计步器恢复

}

*/

@property(readonly, nonatomic) CMPedometerEventType type;

@end


CMPedometerData计步器数据类:


@interface CMPedometerData

//记录开始时间

@property(readonly, nonatomic) NSDate *startDate;

//记录结束时间

@property(readonly, nonatomic) NSDate *endDate;

//步数

@property(readonly, nonatomic) NSNumber *numberOfSteps;

//距离

@property(readonly, nonatomic, nullable) NSNumber *distance;

//通过楼梯上升的楼层数

@property(readonly, nonatomic, nullable) NSNumber *floorsAscended;

//通过楼梯下降的楼层数

@property(readonly, nonatomic, nullable) NSNumber *floorsDescended;

//估算速度

@property(readonly, nonatomic, nullable) NSNumber *currentPace;

//步数频率

@property(readonly, nonatomic, nullable) NSNumber *currentCadence;

//平均速度

@property(readonly, nonatomic, nullable) NSNumber *averageActivePace;

@end

在CoreMotion中,CMStepCounter也是一个记录器类,其比较简易,只在iOS8之前进行使用,解析如下:


@interface CMStepCounter : NSObject

//计步器是否可用

+ (BOOL)isStepCountingAvailable;

//请求一段时间内的步数信息

- (void)queryStepCountStartingFrom:(NSDate *)start

                               to:(NSDate *)end

                          toQueue:(NSOperationQueue *)queue

                      withHandler:(CMStepQueryHandler)handler;

//进行不是更新

- (void)startStepCountingUpdatesToQueue:(NSOperationQueue *)queue

                              updateOn:(NSInteger)stepCounts

                           withHandler:(CMStepUpdateHandler)handler;

//停止计步器更新

- (void)stopStepCountingUpdates;

@end

目录
相关文章
|
3月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
331 4
|
1月前
|
iOS开发 开发者
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
141 67
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
|
3月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
2天前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
21 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
2月前
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
143 66
|
2月前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
87 11
|
2月前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
172 3
|
2月前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
3月前
|
存储 前端开发 Swift
探索iOS开发:从新手到专家的旅程
本文将带您领略iOS开发的奇妙之旅,从基础概念的理解到高级技巧的掌握,逐步深入iOS的世界。文章不仅分享技术知识,还鼓励读者在编程之路上保持好奇心和创新精神,实现个人成长与技术突破。
|
3月前
|
安全 IDE Swift
探索iOS开发之旅:从初学者到专家
在这篇文章中,我们将一起踏上iOS开发的旅程,从基础概念的理解到深入掌握核心技术。无论你是编程新手还是希望提升技能的开发者,这里都有你需要的指南和启示。我们将通过实际案例和代码示例,展示如何构建一个功能齐全的iOS应用。准备好了吗?让我们一起开始吧!

热门文章

最新文章

  • 1
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    23
  • 2
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    21
  • 3
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    141
  • 4
    【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
    223
  • 5
    app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
    87
  • 6
    深入探索iOS开发中的SwiftUI框架
    143
  • 7
    ios样式开关按钮jQuery插件
    58
  • 8
    Android与iOS生态差异深度剖析:技术架构、开发体验与市场影响####
    74
  • 9
    深入探索iOS与Android操作系统的安全性差异
    102
  • 10
    安卓与iOS开发中的跨平台策略:一次编码,多平台部署
    173