iOS开发 蓝牙相关
最近看了几个与蓝牙相关的框架,这里分享给大家。下面提到的三个框架,大家可以看一下,其实涉及到蓝牙开发的方法并没有那么复杂。
一、GameKit
iOS3~iOS7之间使用的框架是GameKit,它是最基本的蓝牙通信框架。连接的必须是两个设备上的同一个应用。连接后可以进行文件的共享,但是仅限于沙盒内的文件。该框架一般用于游戏。
- 开发流程 首先要引入框架:
#import <GameKit/GameKit.h>
- 搜索蓝牙设备
- 创建蓝牙搜索选择器
GKPeerPickerController *pickerController = [[GKPeerPickerController alloc]init];
pickerController.delegate = self;
[pickerController show];
- 重要的代理方法
// 连接蓝牙的方式 在线 附近
-(void)peerPickerController:(GKPeerPickerController\*)picker didSelectConnectionType:(GKPeerPickerConnectionType)type {}
// 获取会话的方式 在线 附近
-(GKSession\*)peerPickerController:(GKPeerPickerController\*)picker sessionForConnectionType:(GKPeerPickerConnectionType)type {
return nil;
}
/*
*peerID:连接成功的设备的ID
*session:当前会话 需要保存下来 才能进行数据的传递
*/
-(void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session {
// 成功后隐藏连接设备界面
[picker dismiss];
// 接受数据的回调 在GameKit中 必须实现********
[session setDataReceiveHandler:self withContext:nil];
// 保存连接成功后创建的会话 (很重要)
self.session = session;
}
// 只要有数据传递过来就会调用(与********方法协同使用)
-(void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context {
if (!data) return;
self.image.image = [UIImage imageWithData:data];
}
// 退出
-(void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker {}
- 发送数据
// GKSendDataReliable 安全模式 依次发送只要有一个发送不成功则终止
// GKSendDataUnreliable 不安全模式 群发,需要响应,所以也需要设置请求超时
[self.session sendDataToAllPeers:data withDataMode:GKSendDataUnreliable error:nil];
- 接受数据回调(我们在上面提到的代理中接受数据的回调)
二、mutipeerConnentivity
该框架是iOS7引入的一个全新的框架用来替换GameKit。特点:多点连接、多用于文件的传输、iOS设备不联网也能跟附近的人聊天。
搜索和传输的方式:① 双方WiFi和蓝牙都没打开:无法完成 ② 双方都开启蓝牙:通过蓝牙发送和传输 ③ 双方都开启WiFi:通过WiFi Direct发现和传输,速度接近AirDrop ④ 双方同时开启了WiFi和蓝牙:模拟AirDrop,通过低功耗蓝牙技术扫描发现握手,然后通过WiFi Direct传输。
开发流程:
① 注册广告 告诉别人 我的设备可以被发现
② 扫描蓝牙设备 实现代理方法
③ 使用一个MCSession对象存储当前会话 实现代理方法
④ 使用MCSession对象 发送和接受数据
- 首先设置一些用到的属性
// 广告标识
#define SERVICE_TYPE @"XXW"
@interface ViewController ()
<MCBrowserViewControllerDelegate,
UIImagePickerControllerDelegate,
UINavigationControllerDelegate,MCSessionDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *ImageView;// 保存会话
@property (strong, nonatomic) MCSession *session;// 发布广告 (延长其生命周期使之持续发布广告)
@property (strong, nonatomic) MCAdvertiserAssistant *assistant;// 当前连接到的设备的peerID
@property (strong, nonatomic) MCPeerID *peerID;
@end
- 这里我们添加几个按钮并关联响应的处理事件
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 根据设备编号创建用户标志peerID
MCPeerID *peerId = [[MCPeerID alloc]initWithDisplayName:[UIDevice currentDevice].name];
self.session = [[MCSession alloc]initWithPeer:peerId];
self.session.delegate = self;
}
- (IBAction)connectAction:(id)sender {
MCBrowserViewController *browserVC = [[MCBrowserViewController alloc]initWithServiceType:SERVICE_TYPE session:self.session];
browserVC.delegate = self;
[self presentViewController:browserVC animated:YES completion:nil];
}
- (IBAction)selectImg:(id)sender {
UIImagePickerController *imgPicker = [[UIImagePickerController alloc]init];
imgPicker.delegate = self;
imgPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[self presentViewController:imgPicker animated:YES completion:nil];
}
- (IBAction)sendImg:(id)sender {
if (!self.ImageView.image) return;
NSData *data = UIImagePNGRepresentation(self.ImageView.image);
[self.session sendData:data toPeers:@[self.peerID] withMode:MCSessionSendDataUnreliable error:nil];
}
// 设置可以被发现
- (IBAction)found:(id)sender {
UISwitch *mySwitch = (UISwitch *)sender;
if (mySwitch.isOn) {
// 注册一个广告 可能一个app发送了多个广告 所以需要给广告绑定一个唯一标示
self.assistant = [[MCAdvertiserAssistant alloc]initWithServiceType:SERVICE_TYPE discoveryInfo:nil session:self.session];
// 发布广告(当该代码块执行完成后,创建的变量就会被销毁,所以要延长其生命周期,使之持续发布广告)
[_assistant start];
}
- 代理方法的实现
#pragma mark -- 扫描设备的代理 --
// 连接成功
- (void)browserViewControllerDidFinish:(MCBrowserViewController *)browserViewController {
[browserViewController dismissViewControllerAnimated:YES completion:nil];
}
// 退出连接
- (void)browserViewControllerWasCancelled:(MCBrowserViewController *)browserViewController {
[browserViewController dismissViewControllerAnimated:YES completion:nil];
}
// 连接那个设备
- (BOOL)browserViewController:(MCBrowserViewController *)browserViewController shouldPresentNearbyPeer:(MCPeerID *)peerID withDiscoveryInfo:(nullable NSDictionary<NSString *, NSString *> *)info {
self.peerID = peerID;
return YES;
}
#pragma mark -- session会话的代理方法 --
// 该方法必须实现,不然程序会崩
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state {}
// 获取数据回调
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID {
dispatch_async(dispatch_get_main_queue(), ^{
self.ImageView.image = [UIImage imageWithData:data];
});
}
#pragma mark -- 图片获取器代理方法 --
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
self.ImageView.image = info[UIImagePickerControllerOriginalImage];
[picker dismissViewControllerAnimated:YES completion:nil];}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:nil];
}
三、CoreBlueTooth
- 简介:① 可用于第三方蓝牙设备交互,但是设备必须支持蓝牙4.0,没有同一应用下这个限制。② iPhone的设备必须是4S或更新。③ iPad设备必须是iPad mini或更新。④ iOS的系统必须是iOS 6或更新。⑤ 蓝牙4.0以“低功耗”著称,所以一直被称为BLE(bluetooth low energy)。
- 条件限制:① 使用模拟器进行调试必须满足:Xcode 4.6 iOS 6.1 (只限于这个版本,既不能高也不能低)。 ② 使用场景:运动手环、智能家居、拉卡拉蓝牙刷卡器。
- 核心概念:① CBCentralManager:中心设备(用来连接到外部设备的管家)② CBPeripheralManager:外部设备(第三方的蓝牙4.0设备)
- 开发步骤:① 建立中心管家 ② 扫描外设(discover) ③ 连接外设 ④ 扫描外设中的服务和特征(服务和特征的关系) ⑤ 与外设做数据交换(在指定的特征下做相应的操作)⑥ 断开连接
总结
这里是我对蓝牙开发框架的简单了解,因为设备能力有限无法进行实际的验证,非常抱歉。但是还是希望能够有时间进行深入的学习。在我接触的过程中,发现蓝牙开发也不是那么的复杂,可能实际操作起来也不会很容易。当前最流行的是使用CoreBluetooth框架进行蓝牙的开发(简称BLE),因为时间有限,暂时还没有对此进行深入的学习,希望有时间能够完成进一步的学习吧!