实用框架:
CoreBluetooth.framework(时下热门)
可用于第三方蓝牙设备交互,必须要支持蓝牙4.0
硬件至少是4s,系统至少是iOS6
蓝牙4.0以低功耗著称,一般也叫BLE(Bluetooth Low Energy)
目前应用比较多的案例:运动手坏、嵌入式设备、智能家居
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的核心结构图:
Core Bluetooth的基本常识:
每个蓝牙4.0设备都是通过服务(Service)和特征(Characteristic)来展示自己的
一个设备必然包含一个或多个服务,每个服务下面又包含若干个特征
特征是与外界交互的最小单位
比如说,一台蓝牙4.0设备,用特征A来描述自己的出厂信息,用特征B来收发数据
服务和特征都是用UUID来唯一标识的,通过UUID就能区别不同的服务和特征
设备里面各个服务(service)和特征(characteristic)的功能,均由蓝牙设备硬件厂商提供,比如哪些是用来交互(读写),哪些可获取模块信息(只读)等
Core Bluetooth的开发步骤:
建立中心设备
// 1.创建一个蓝牙对象
self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
扫描外设(Discover Peripheral):
// 2.进行检索操作
// nil: 任意的外设
[self.manager scanForPeripheralsWithServices:nil options:nil];
连接外设(Connect Peripheral):
// 3.如果发现了蓝牙设备,就会调用这个方法
(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI;
{
// 4.连接外设(别的蓝牙设备)
[self.manager connectPeripheral:peripheral options:0];
}
扫描外设中的服务和特征(Discover Services And Characteristics):
// 5.连接上某个设备后,调用这个方法-
(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
// 6.尝试发现外设的某项服务
[peripheral discoverServices:nil];peripheral.delegate = self;
}
利用特征与外设做数据交互(Explore And Interact):
// 7.如果发现某一项服务,就调用这个方法
-
(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error;
{
if (error) {return;
}
for (CBService *service in peripheral.services) {
if ([service.UUID.UUIDString isEqualToString:@"123"]) {
// 寻找所对应的特征
[peripheral discoverCharacteristics:nil forService:service];
}
}
}
// 8.找到这个服务所组成的特征时,调用这个方法
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
NSLog(@"可以进行一些通讯操作.传值操作");
}
// 如果蓝牙的状态改变的话,就会调用这个方法
// 这个方法一定要实现,要不然会出错.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central;
{
NSLog(@"蓝牙的状态改变了");
}
更多框架:
GameKit.framework(用法简单)
只能用于iOS设备之间的连接,多用于游戏(比如五子棋对战),从iOS7开始过期
MultipeerConnectivity.framework
只能用于iOS设备之间的连接,从iOS7开始引入,用于替代GameKit
ExternalAccessory.framework
可用于第三方蓝牙设备交互,但是蓝牙设备必须经过苹果MFi认证(国内较少)
简单介绍GameKit:
使用GameKit框架,可以在游戏中增加对等连接,又称对端连接或点对点连接,Peer To Peer。
使用GameKit框架中的对等网络连接API,可以在游戏玩家之间建立一个对等网络,并在游戏/应用实例之间交换数据。
GameKit框架可以使用蓝牙在玩家之间创建网络,玩家甚至不需要连接到互联网,就可以彼此对战。
通过蓝牙实现对等网络连接:
1.为玩家双方呈现一个GKPeerPickerController,提供了一个标准的用户界面连接两台设备
2.ViewControoler遵循GKPeerPickerControllerDelegate协议,处理来自GKPeerPickerController(对端选择器)的信息
3.建立连接后,使用GKSession类可以向对端设备发送数据
4.在receiveData:fromPeer:inSession:context代理方法中编写代码来处理接收到的数据
GameKit的蓝牙开发步骤:
显示可以连接的蓝牙设备列表
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
self.session = session;
}
处理接收到的蓝牙数据
-(void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context {
}
利用GKSession给其他设备发送数据
给指定的连接设备发送数据
-(BOOL)sendData:(NSData)datatoPeers:(NSArray)peerswithDataMode:(GKSendDataMode)mode error:(NSError *)error;
给所有连接的设备发送数据
-(BOOL)sendDataToAllPeers:(NSData)datawithDataMode:(GKSendDataMode)mode error:(NSError **)error;
GameKit的蓝牙开发注意:
只能用于iOS设备之间的连接
只能用于同一个应用程序之间的连接
最好别利用蓝牙发送比较大的数据