这里主要做个记录。
ios中其实提供了四个框架可以让我们去实现蓝牙连接
其中GameKit框架是在ios7的时候过期了,之前常用于游戏的连接,GameKit框架可以使用蓝牙在玩家之间创建一个对等连接,然后彼此之间可以对战,苹果取而代之的是MultipeerConnectivity,这两个框架都只能用于ios设备直接的连接。
ExternalAccessory框架是用于第三方蓝牙设备交互的,但是该蓝牙设备必须要经过苹果的MFi的认证。什么是苹果的MFi认证其实就是是苹果公司对其授权配件厂商生产的外置配件的一种标识使用许可。
最后一个就是CoreBluetooth这个框架一般来说可能会使用的比较多,但是设备必须要支持蓝牙4.0,蓝牙4.0以低功耗著称,所以也叫BLE(Bluetooth Low Energy)
先简单的说一下GameKit框架的使用步骤
1、先去创建GKPeerPickerController就是一个连接控制器也就是下面这个控制器
2、就是去设置代理,通过实现代理方法去获取数据
3、就是去显示控制器了,这个控制器其实和AlertView很像的都是这样的形式
4、就是去实现GKPeerPickerControllerDelegate这个的代理方法
5、设置句柄,让这个句柄去实现一个接受到数据的方法也就是下面这个方法
- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
这个方法是必须要去实现的,我们可以看到文档中是这么描述的
6、使控制器消失
代码的简单实现如下所示,这里就是想把图片发给连接的设备来显示出来,以这个目的来实现的。
#import "ViewController.h"
#import <GameKit/GameKit.h>
@interface ViewController ()<UINavigationControllerDelegate, UIImagePickerControllerDelegate,GKPeerPickerControllerDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (nonatomic ,strong)GKSession *session;
@end
@implementation ViewController
- (IBAction)connectDevice:(id)sender {
//1、创建连接控制器
GKPeerPickerController * picker = [GKPeerPickerController new];
//2、设置代理去获取数据
picker.delegate = self;
//显示控制器
[picker show];
}
#pragma mark 实现GKPeerPickerControllerDelegate的代理方法
//这个代理方法会在连接到另一台设备的时候会去调用
//其中peerId 就是另一台设备得到ID,session是一个会话类,用来接收和发送数据,发送数据过去的时候我们肯定是需要一个session的,所以我们需要去保存为属性
-(void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session
{
//1、把session赋值给我们设置的属性
self.session = session;
//2、设置数据接收的句柄,其实就是相当于设置代理一样的,这里设置好之后,如果收到了数据就会去调用这个句柄的一个方法-receiveData:fromPeer:inSession:context:
[self.session setDataReceiveHandler:self withContext:nil];
//连接到设备的时候,让控制器dismiss
[picker dismiss];
}
//下面这个方法就是接受到了数据之后去调用的
- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
{
UIImage * image = [UIImage imageWithData:data];
self.imageView.image = image;
}
- (IBAction)choosePicture:(id)sender {
//判断是否可用
if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
NSLog(@"不可用");
return;
}
//创建控制器
UIImagePickerController * picker = [UIImagePickerController new];
//设置类型
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
//设置代理
picker.delegate = self;
[self presentViewController:picker animated:YES completion:^{
}];
}
//实现代理方法,获取图片
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
self.imageView.image = info[UIImagePickerControllerOriginalImage];
//关闭控制器
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)sendPicture:(id)sender {
//将image转换为Data
NSData * data = UIImageJPEGRepresentation(self.imageView.image, 0.7);
//Data的处理模式
// GKSendDataReliable, 发送失败之后,还是会继续的去发送,直到发送成功
// GKSendDataUnreliable, 如果发送一次之后就不会再次的去发送了。
//发送数据的方法,给所有的Peer的对象
[self.session sendDataToAllPeers:data withDataMode:GKSendDataReliable error:nil];
}
关于Core Bluetooth,网上的介绍有很多,我也不在此介绍了,就简单的说几个概念把
CoreBluetooth可以分为两大模块,中心模式就是以你的app作为中心,连接其他的外设的场景,外设模式就是使用手机作为外设
连接其他中心设备操作的场景
中间设备: CBCentralManager
外设: 也就是你的中心设备要连接的设备
广播:外部设备不停的散播的蓝牙信号,让中心设备可以扫描到,也是我们开发中接收数据的入口。
服务:外部设备在与中心设备连接后会有服务,可以理解成一个功能模块,中心设备可以读取服务,筛选我们想要的服务,并从中获取出我们想要特征。一个设备可以有多个服务
特征:服务中的一个单位,一个服务可以有多个特征,特征会有一个value,一般我们向蓝牙设备写入数据、从蓝牙设备读取数据就是这个value。特征是与外界交互的最小的单位
UUID:区分不同服务和特征的唯一标识,使用这个我们可以区别出不同的特征和服务
设备里面的服务啊特征啊,这些功能均由蓝牙设备硬件厂商提供,哪些用来交互,哪些用来只能读取,都会有说明。
我们使用Core Bluetooth是以中心来开发的话步骤大致如下
1、建立中心设备
2、扫描外设
3、连接外设
4、先去扫描外设中的服务再去扫描特征
5、利用特征和外设进行数据交互
6、断开连接
摘抄网络
苹果手机可以作为蓝牙外设端,被蓝牙中央端来扫描连接交互数据,实现模拟蓝牙外设硬件。通过阅读CoreBluetooth库,可以找到一个CBPeripheralManager的类,该类主要的作用就是允许你来管理发布services,把这些services广播给其他的设备。