蓝牙

概述

现有蓝牙实现方案

GameKit.framework(用法简单)

只能用于iOS设备之间的连接,多用于游戏(比如五子棋对战),从iOS7开始过期

MultipeerConnectivity.framework

只能用于iOS设备之间的连接,从iOS7开始引入,主要用于文件共享(仅限于沙盒的文件)

ExternalAccessory.framework

可用于第三方蓝牙设备交互,但是蓝牙设备必须经过苹果MFi认证(国内较少)

CoreBluetooth.framework(时下热门)

可用于第三方蓝牙设备交互,必须要支持蓝牙4.0
硬件至少是4s,系统至少是iOS6
蓝牙4.0以低功耗著称,一般也叫BLE(Bluetooth Low Energy)
目前应用比较多的案例:运动手坏、嵌入式设备、智能家居

MultipeerConnectivity用法跟GameKit很像,ExternalAccessory很少用,因此简单记录下GameKit和CoreBluetooth(处于Core OS Layer)在蓝牙上的用法

GameKit

  gamekit只能用于iOS设备间传递且还设备运行的必须是同一个应用程序,此外系统提供的解决方案没有进度显示UE很差(一般只用于小数据传递)

开发步骤:

1、显示可以连接的蓝牙设备列表

GKPeerPickerController *ppc = [[GKPeerPickerController alloc] init];
ppc.delegate = self; // 设置代理
[ppc show];

2、在代理方法中监控蓝牙的连接

- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session {
    NSLog(@"连接到设备:%@", peerID);
    // 关闭蓝牙设备显示界面
    [picker dismiss];
    // 设置接收到蓝牙数据后的监听器
    [session setDataReceiveHandler:self withContext:nil];
    // 保存session
    self.session = session;
}

PS:成为GKSession的Handler的类必须实现receiveData: fromPeer: inSession: context: 方法

(采用的是方法回调方式)
3、处理接收到的蓝牙数据

- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context {
    //处理逻辑。。。
}

4、利用GKSession给其他设备发送数据

//给指定的连接设备发送数据
- (BOOL)sendData:(NSData *) data toPeers:(NSArray *)peers withDataMode:(GKSendDataMode)mode error:(NSError **)error;
//给所有连接的设备发送数据
- (BOOL)sendDataToAllPeers:(NSData *) data withDataMode:(GKSendDataMode)mode error:(NSError **)error;

CoreBluetooth

概述

>每个蓝牙4.0设备都是通过服务(Service)和特征(Characteristic)来展示自己的
  一个设备必然包含一个或多个服务,每个服务下面又包含若干个特征

>特征是与外界交互的最小单位
  eg: 一台蓝牙4.0设备,用特征A来描述自己的出厂信息,用特征B来收发数据

>服务和特征都是用UUID来唯一标识的,通过UUID就能区别不同的服务和特征

>设备里面各个服务(service)和特征(characteristic)的功能,均由蓝牙设备硬件厂商提供,比如哪些是用来交互(读写),哪些可获取模块信息(只读)等

Core Bluetooth的开发步骤

1.建立中心设备

   // 创建中心设备
    CBCentralManager *mgr = [[CBCentralManager alloc] init];
    self.mgr = mgr;
    
    // 设置代理
    mgr.delegate = self;

2.扫描外设(Discover Peripheral)

//利用中心设备扫描外部设备
//如果指定数组代表只扫描指定的设备
[mgr scanForPeripheralsWithServices:nil options:nil];

#pragma mark - CBCentralManagerDelegate
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral 
      advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI { // 保存扫描到得外部设备 // 判断如果数组中不包含当前扫描到得外部设置才保存 if (![self.peripherals containsObject:peripheral]) { peripheral.delegate = self; [self.peripherals addObject:peripheral]; } }

3.连接外设(Connect Peripheral)

    for (CBPeripheral *peripheral in self.peripherals) {
        //  连接外设
        [self.mgr connectPeripheral:peripheral options:nil];
    }

//  连接外设成功调用
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    // 扫描外设中得服务
    [peripheral discoverServices:nil];
}

//连接外设失败调用
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    
}

4.扫描外设中的服务和特征(Discover Services And Characteristics)

#pragma makr - CBPeripheralDelegate
/**
 *  只要扫描到服务就会调用
 *
 *  @param peripheral 服务所在的外设
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    // 获取外设中所有扫描到得服务
    NSArray *services = peripheral.services;
    for (CBService *service in services) {
        // 拿到需要的服务
        if ([service.UUID.UUIDString isEqualToString:@"123"])
        {
            // 从需要的服务中查找需要的特征
            // 从peripheral中得service中扫描特征
            [peripheral discoverCharacteristics:nil forService:service];
        }
    }
}

/**
 *  只要扫描到特征就会调用
 *
 *  @param peripheral 特征所属的外设
 *  @param service    特征所属的服务
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    // 拿到服务中所有的特诊
    NSArray *characteristics =  service.characteristics;
    // 遍历特征, 拿到需要的特征处理
    for (CBCharacteristic * characteristic in characteristics) {
        if ([characteristic.UUID.UUIDString isEqualToString:@"xxxx"]) {
          .....
        }
    }
}

5.利用特征与外设做数据交互(Explore And Interact)
6.断开连接(Disconnect)

 

posted @ 2015-09-04 10:49  shanhua  阅读(218)  评论(0编辑  收藏  举报