Sensible
传感器
- 感应、检测装置
- iPhone内置的传感器有
- 运动传感器\加速度传感器\加速计(Motion/Accelerometer Sensor)
- 环境光传感器(Ambient Light Sensor)
- 距离传感器(Proximity Sensor)
- 磁力计传感器(Magnetometer Sensor)
- 内部温度传感器(Internal Temperature Sensor)
- 湿度传感器(Moisture Sensor)
- 陀螺仪(Gyroscope)
距离传感器
- 打开距离传感器,监听是否有物品靠近传感器
[UIDevice currentDevice].proximityMonitoringEnabled = YES;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityDidChange) name:UIDeviceProximityStateDidChangeNotification object:nil];
- 实现回调方法
- (void)proximityDidChange
{
if ([UIDevice currentDevice].proximityState) {
NSLog(@"有物品靠近");
}else
{
NSLog(@"有物品离开");
}
}
加速计
- 作用 : 检测设备的运动(比如摇晃
- 经典应用场景 : 摇一摇 、计步器
- 检测设备在X、Y、Z轴上的加速度,判断出在各个方向上的作用力度
- 在iOS4以前:使用UIAccelerometer,到了iOS5就已经过期
- 从iOS4开始:CoreMotion.framework
UIAccelerometer ios 5 已过期
- 创建单粒对象,设置代理
// 获取单粒对象
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
// 设置代理
accel.delegate = self;
// 设置采样间隔
[accel setUpdateInterval:0.5];
- 遵守UIAccelerometerDelegate代理协议,实现回调方法
/**
* x轴:正常拿手机的左侧向下为负,右侧则为正
* y轴:正常拿手机为负,将上面朝下则为正
* z轴:正常拿手机的背面朝下为负,正面朝下则为正
*/
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
NSLog(@"x:%f y:%f z:%f",acceleration.x,acceleration.y,acceleration.z);
}
CMMotionManager
- CoreMotion/CoreMotion.h
- Core Motion获取数据的两种方式
- pull
- 在有需要的时候,再主动去采集数据
- pull
// 创建运动管理者对象
CMMotionManager *manager = [[CMMotionManager alloc] init];
// 判断加速计是否可用(最好判断)
if (manager.isAccelerometerAvailable) { // 加速计可用 }
// 开始采样
- (void)startAccelerometerUpdates;
// 在需要的时候采集加速度数据
CMAcceleration acc = manager.accelerometerData.acceleration;
NSLog(@"%f, %f, %f", acc.x, acc.y, acc.z);
- push
- 实时采集所有数据(采集频率高)
创建运动管理者对象
CMMotionManager *manager = [[CMMotionManager alloc] init];
判断加速计是否可用(最好判断)
if (manager.isAccelerometerAvailable) {
// 加速计可用
}
设置采样间隔
manager.accelerometerUpdateInterval = 1.0/30.0; // 1秒钟采样30次
开始采样(采样到数据就会调用handler,handler会在queue中执行)
- (void)startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMAccelerometerHandler)handler;
摇一摇的实现
- 方法1:通过分析加速计数据来判断是否进行了摇一摇操作(比较复杂)
- 方法2:iOS自带的Shake监控API(非常简单)
判断摇一摇的步骤:实现3个摇一摇监听方法
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event /** 检测到摇动 */
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event /** 摇动取消(被中断) */
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event /** 摇动结束 */
陀螺仪
pull
// 0.创建运动管理者对象 CMMotionManager *manager = [[CMMotionManager alloc] init]; // 1.判断陀螺仪是否可用 if (![self.manager isGyroAvailable]) { NSLog(@"手机该换了"); return; } // 2.开始采样 [self.manager startGyroUpdates]; // 3.获取陀螺仪信息 CMRotationRate rate = self.mgr.gyroData.rotationRate; NSLog(@"x:%f y:%f z:%f", rate.x, rate.y, rate.z);
push
// 0.创建运动管理者对象
CMMotionManager *manager = [[CMMotionManager alloc] init];
// 1.判断陀螺仪是否可用
if (![self.manager isGyroAvailable]) {
NSLog(@"手机该换了");
return;
}
// 2.设置采样间隔
self.manager.gyroUpdateInterval = 0.3;
// 3.开始采样
[self.manager startGyroUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMGyroData *gyroData, NSError *error) {
if (error) return;
CMRotationRate rate = gyroData.rotationRate;
NSLog(@"x:%f y:%f z:%f", rate.x, rate.y, rate.z);
}];
磁力感应计
// 0.创建运动管理者对象
CMMotionManager *manager = [[CMMotionManager alloc] init];
// 1.判断磁力计是否可用
if (!self.manager.isMagnetometerAvailable) {
return;
}
// 2.设置采样间隔
self.manager.magnetometerUpdateInterval = 0.3;
// 3.开始采样
[self.manager startMagnetometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMMagnetometerData *magnetometerData, NSError *error) {
if (error) return;
CMMagneticField field = magnetometerData.magneticField;
NSLog(@"x:%f y:%f z:%f", field.x, field.y, field.z);
}];
}
计步器
- CMStepCounter iOS 8 已过期
CMStepCounter counter = [[CMStepCounter alloc] init]
if (![CMStepCounter isStepCountingAvailable]) {
NSLog(@"计步器不可用");
return;
}
[self.counter startStepCountingUpdatesToQueue:[NSOperationQueue mainQueue] updateOn:10 withHandler:^(NSInteger numberOfSteps, NSDate * _Nonnull timestamp, NSError * _Nullable error) {
self.stepLabel.text = [NSString stringWithFormat:@"一共走了%zd步",numberOfSteps];
NSLog(@"%zd",numberOfSteps);
}];
蓝牙
iOS中提供了4个框架用于实现蓝牙连接
GameKit.framework(用法简单)
- 只能用于iOS设备之间的连接,多用于游戏(比如五子棋对战),从iOS7开始过期
MultipeerConnectivity.framework
- 只能用于iOS设备之间的连接,从iOS7开始引入
ExternalAccessory.framework
- 可用于第三方蓝牙设备交互,但是蓝牙设备必须经过苹果MFi认证(国内较少)
CoreBluetooth.framework(时下热门)
- 可用于第三方蓝牙设备交互,必须要支持蓝牙4.0
- 硬件至少是4s,系统至少是iOS6
- 蓝牙4.0以低功耗著称,一般也叫BLE(Bluetooth Low Energy)
- 目前应用比较多的案例:运动手坏、嵌入式设备、智能家居
GameKit的蓝牙开发步骤
- 注意点:
- 只能用于iOS设备之间的连接
- 只能用于同一个应用程序之间的连接
- 最好别利用蓝牙发送比较大的数据
显示可以连接的蓝牙设备列表
GKPeerPickerController *ppc = [[GKPeerPickerController alloc] init];
ppc.delegate = self;
[ppc show];
在代理方法中监控蓝牙的连接
- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session {
NSLog(@"连接到设备:%@", peerID);
// 关闭蓝牙设备显示界面
[picker dismiss];
// 设置接收到蓝牙数据后的监听器
[session setDataReceiveHandler:self withContext:nil];
// 保存session
处理接收到的蓝牙数据
- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context {
}
利用GKSession给其他设备发送数据
给指定的连接设备发送数据
- (BOOL)sendData:(NSData *) data toPeers:(NSArray *)peers withDataMode:(GKSendDataMode)mode error:(NSError **)error;
给所有连接的设备发送数据
- (BOOL)sendDataToAllPeers:(NSData *) data withDataMode:(GKSendDataMode)mode error:(NSError **)error;
Core Bluetooth
- Core Bluetooth测试比较麻烦,正常情况下,得至少有2台真实的蓝牙4.0设备
如何让iOS模拟器也能测试蓝牙4.0程序?
- 买一个CSR蓝牙4.0 USB适配器,插在Mac上
- 在终端输入sudo nvram bluetoothHostControllerSwitchBehavior="never"
- 重启Mac
- 用Xcode 4.6调试代码,将程序跑在iOS 6.1的模拟器上
(苹果把iOS 7.0模拟器对BLE的支持移除掉了)
Core Bluetooth的使用场景
- 运动手环、智能家居、嵌入式设备等等(金融刷卡器、心电测量器)
基本常识
- 每个蓝牙4.0设备都是通过服务(Service)和特征(Characteristic)来展示自己的
一个设备必然包含一个或多个服务,每个服务下面又包含若干个特征
特征是与外界交互的最小单位
比如说,一台蓝牙4.0设备,用特征A来描述自己的出厂信息,用特征B来收发数据
服务和特征都是用UUID来唯一标识的,通过UUID就能区别不同的服务和特征
设备里面各个服务(service)和特征(characteristic)的功能,均由蓝牙设备硬件厂商提供,比如哪些是用来交互(读写),哪些可获取模块信息(只读)等