您的位置:首页 > 移动开发 > IOS开发

iOS开发 -GameKit蓝牙开发

2015-10-26 09:47 381 查看

蓝牙4.0

蓝牙4.0是2012年最新蓝牙版本,是3.0的升级版本;较3.0版本更省电、成本低、3毫秒低延迟、超长有效连接距离、AES-128加密等;通常用在蓝牙耳机、蓝牙音箱等设备上。

蓝牙技术联盟(Bluetooth SIG)2010年7月7日宣布,正式采纳蓝牙4.0核心规范(Bluetooth Core Specification Version 4.0 ),并启动对应的认证计划。会员厂商可以提交其产品进行测试,通过后将获得蓝牙4.0标准认证。 该技术拥有极低的运行和待机功耗,使用一粒纽扣电池甚至可连续工作数年之久。


iOS中蓝牙的实现方案

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框架简介

使用GameKit框架,可以在游戏中增加对等连接,又称对端连接或点对点连接,Peer To Peer。

使用GameKit框架中的对等网络连接API,可以在游戏玩家之间建立一个对等网络,并在游戏/应用实例之间交换数据。

GameKit框架可以使用蓝牙在玩家之间创建网络,玩家甚至不需要连接到互联网,就可以彼此对战。

通过蓝牙实现对等网络连接

为玩家双方呈现一个GKPeerPickerController,提供了一个标准的用户界面连接两台设备

ViewControoler遵循GKPeerPickerControllerDelegate协议,处理来自GKPeerPickerController(对端选择器)的信息

建立连接后,使用GKSession类可以向对端设备发送数据

在receiveData:fromPeer:inSession:context代理方法中编写代码来处理接收到的数据

//发送数据方法
[_peerSession sendDataToAllPeers:data withDataMode:GKSendDataReliable error:&error];

//接收数据方法
- (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context;


如果要通过网络发送自定义对象,需要使用NSKeyedArchiver方法归档自定义对象,然后再发送归档后的NSData

自定义对象需要遵从NSCoding协议,并实现相应的归档和恢复方法

接收端接收到数据之后,使用NSKeyedUnarchiver方法恢复数据

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 *) data toPeers:(NSArray *)peers withDataMode:(GKSendDataMode)mode error:(NSError **)error;

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


GameKit的蓝牙开发注意

只能用于iOS设备之间的连接

只能用于同一个应用程序之间的连接

最好别利用蓝牙发送比较大的数据

GameKit蓝牙开发实例

#import "ViewController.h"
#include <GameKit/GameKit.h>

@interface ViewController ()<UINavigationControllerDelegate, UIImagePickerControllerDelegate, GKPeerPickerControllerDelegate>
/**
*  连接
*/
- (IBAction)connect;
/**
*  选择图片
*/
- (IBAction)selectedPhoto;
/**
*  发送
*/
- (IBAction)send;

@property (weak, nonatomic) IBOutlet UIImageView *customIV;
/**
*  会话
*/
@property (nonatomic, strong) GKSession *session;
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (IBAction)connect {

// 1.创建选择其他蓝牙设备的控制器
GKPeerPickerController *peerPk = [[GKPeerPickerController alloc] init];
// 2.成为该控制器的代理
peerPk.delegate = self;
// 3.显示蓝牙控制器
[peerPk show];
}
#pragma mark - GKPeerPickerControllerDelegate
// 4.实现dialing方法
/**
*  当蓝牙设备连接成功就会调用
*
*  @param picker  触发时间的控制器
*  @param peerID  连接蓝牙设备的ID
*  @param session 连接蓝牙的会话(可用通讯), 以后只要拿到session就可以传输数据
*/
- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session
{
NSLog(@"%@", peerID);
// 1.保存会话
self.session = session;

// 2.设置监听接收传递过来的数据
/*
Handler: 谁来处理接收到得数据
withContext: 传递数据
*/
[self.session setDataReceiveHandler:self withContext:nil];

// 2.关闭显示蓝牙设备控制器
[picker dismiss];
}
/**
*  接收到其它设备传递过来的数据就会调用
*
*  @param data    传递过来的数据
*  @param peer    传递数据设备的ID
*  @param session 会话
*  @param context 注册监听时传递的数据
*/
- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
{
//    NSLog(@"%s", __func__);
// 1.将传递过来的数据转换为图片(注意: 因为发送的时图片, 所以才需要转换为图片)
UIImage *image = [UIImage imageWithData:data];
self.customIV.image = image;
}

- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker
{

}

- (IBAction)send {
// 利用session发送图片数据即可
// 1.取出customImageView上得图片, 转换为二进制
UIImage *image =  self.customIV.image;
NSData *data = UIImagePNGRepresentation(image);

/*
GKSendDataReliable, 数据安全的发送模式, 慢
GKSendDataUnreliable, 数据不安全的发送模式, 快
*/

/*
data: 需要发送的数据
DataReliable: 是否安全的发送数据(发送数据的模式)
error: 是否监听发送错误
*/
[self.session sendDataToAllPeers:data withDataMode:GKSendDataReliable error:nil];
}

- (IBAction)selectedPhoto
{

// 1.创建图片选择控制器
UIImagePickerController *imagePk = [[UIImagePickerController alloc] init];
// 2.判断图库是否可用打开
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
// 3.设置打开图库的类型
imagePk.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;

imagePk.delegate = self;

// 4.打开图片选择控制器
[self presentViewController:imagePk animated:YES completion:nil];
}
}
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//    NSLog(@"%@", info);
self.customIV.image = info[UIImagePickerControllerOriginalImage];

[picker dismissViewControllerAnimated:YES completion:nil];
}

@end


扫描周围设备

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息