藍牙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中提供了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框架,可以在游戲中增加對等連接,又稱對端連接或點對點連接,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方法恢復數據
//顯示可以連接的藍牙設備列表
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;
只能用於iOS設備之間的連接
只能用於同一個應用程序之間的連接
最好別利用藍牙發送比較大的數據
#import ViewController.h
#include
@interface ViewController ()
/**
* 連接
*/
- (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