侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

iOS开发之CoreMotion框架的应用

2023-12-12 星期二 / 0 评论 / 0 点赞 / 44 阅读 / 18108 字

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

iOS开发之CoreMotion框架的应用

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

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

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

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

一、CoreMotion框架整体结构

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

从上图中可以看出,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;@endtypedef 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

 

广告 广告

评论区