藍牙
mutipeerConnectivity
簡介
* iOS 7引入的一個全新框架
* 多點鏈接
* 替代GameKit框架
* 多用於文件的傳輸
* iOS設備不聯網也能跟附近的人聊天
* FireChat
* See You Around
* 以上近場聊天App都是基於mutipeerConnectivity框架
* 搜索和傳輸的方式
* 雙方WIFI和藍牙都沒有打開:沒法實現
* 雙方都開啓藍牙:經過藍牙發現和傳輸
* 雙方都開啓WIFI:經過WIFI Direct發現和傳輸,速度接近AirDrop
* 雙方同時開啓了WIFI和藍牙:模擬AirDrop,經過低功耗藍牙技術掃描發現握手,而後經過WIFI Direct傳輸
案例界面搭建
開發思路步驟
1. 註冊一個廣播 告訴別人 個人設備是能夠被發現
2. 掃描藍牙設備 須要實現代理方法
3. 使用一個MCSession對象 存儲當前會話 須要實現代理方法
4. 使用MCSession對象 發送和接收數據
鏈接設備
// 建立MCSession對象
// initWithPeer:設備的ID
// 用於存放當前的鏈接的會話
self.mc_Session = [ [MCSession alloc] initWithPeer:[[MCPeerID alloc] initWithDisplayName:[UIDevice currentDevice].name]];
#define SERVICE_TYPE @"SLZeng"
/**
* 只要開啓了可被搜索的廣播,那麼鏈接藍牙按鈕就不可點
*/
- (IBAction)foundConnect:(id)sender {
UISwitch *switchBtn = (UISwitch *)sender;
if (switchBtn.isOn) {
// 廣播對象,告訴其它的設備他們是可用的
if (self.advertiserAssistant == nil) {
// 建立廣播對象
// initWithServiceType: 廣播類型的標示(由於廣播可能比較多,因此最好每一個廣播綁定一個惟一標示)
// session:當前會話
// discoveryInfo: 廣播信息
self.advertiserAssistant = [[MCAdvertiserAssistant alloc] initWithServiceType:SERVICE_TYPE discoveryInfo:nil session:self.mc_Session];
}
// 開啓廣播
[self.advertiserAssistant start];
self.connectBT.enabled = NO;
}else{
self.connectBT.enabled = YES;
}
}
- (IBAction)connectBlueTooth {
// 建立搜索藍牙設備控制器
MCBrowserViewController *mbVC = [[MCBrowserViewController alloc] initWithServiceType:SERVICE_TYPE session:self.mc_Session];
// 設置控制器代理
mbVC.delegate = self;
// 跳轉到搜索控制器
[self presentViewController:mbVC animated:YES completion:nil];
}
選擇數據
- (IBAction)selectImage {
// 1. 建立圖片選擇器
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
// 2. 判斷圖片選擇器是否可用
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum]) {
// 選擇器打開的類型
imgPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
// 設置代理
imgPicker.delegate = self;
// 打開圖片選擇器
[self presentViewController:imgPicker animated:YES completion:nil];
}
}
// 選擇完畢調用
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
// NSLog(@"info == %@",info);
// 設置顯示圖片
self.showImage.image = info[UIImagePickerControllerOriginalImage];
// 隱藏圖片顯示器
[picker dismissViewControllerAnimated:YES completion:nil];
}
/**
* 鏈接完成
*
* @param browserViewController 搜索控制器
*/
- (void)browserViewControllerDidFinish:(MCBrowserViewController *)browserViewController
{
[browserViewController dismissViewControllerAnimated:YES completion:nil];
NSLog(@"%s %d",__func__,__LINE__);
}
發送數據
#pragma mark - MCBrowserViewControllerDelegate
/**
* 鏈接成功
*
* @param browserViewController 搜索控制器
* @param peerID 鏈接上的設備ID
* @param info 鏈接的信息
*
* @return YES : 只發送鏈接上的用戶
*/
- (BOOL)browserViewController:(MCBrowserViewController *)browserViewController
shouldPresentNearbyPeer:(MCPeerID *)peerID
withDiscoveryInfo:(nullable NSDictionary<NSString *, NSString *> *)info
{
self.peerID = peerID;
NSLog(@"info == %@ peer = %@",info, peerID);
return YES;
}
- (IBAction)sendImage {
// 判斷是否有圖片
if (!self.showImage.image) return;
// 獲取圖片
UIImage *image = self.showImage.image;
// 將圖片轉換成NSData類型
NSData *data = UIImagePNGRepresentation(image);
/**
* 發送數據
* toPeers : 發給的設備ID的數組
* withMode: 發送模式,是不是安全模式
*/
if (self.peerID != nil) {
[self.mc_Session sendData:data toPeers:@[self.peerID] withMode:MCSessionSendDataUnreliable error:nil];
}
}
接收數據
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID
{
NSLog(@"%s %d",__func__, __LINE__);
NSLog(@"data = %@, peer = %@", data, peerID);
}
顯示數據
/**
* 接收到數據的時候調用
*
* @param session 會話
* @param data 數據
* @param peerID 設備的ID
*/
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID
{
NSLog(@"%s %d",__func__,__LINE__);
// NSLog(@"data = %@ , peer = %@",data,peerID);
UIImage *image = [[UIImage alloc] initWithData:data];
if(image != nil){
// 設置數據
dispatch_async(dispatch_get_main_queue(), ^{
self.showImage.image = image;
});
}
}
- 只要設置MCSeesion代理,必須實現的代理方法,否則報錯。
/**
* 會話狀態發生改變的時候調用
*
* @param session 會話
* @param peerID 設備的ID
* @param state 狀態
*/
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
{
NSLog(@"%s %d",__func__,__LINE__);
}